Commit Graph
200 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Sonnet 4.6 046803bd15 feat(ingest_paciente): modo insertar/upsert — migración inicial no pisa existentes
Nuevo campo 'modo' en el body:
- "insertar": si la cédula ya existe devuelve skipped sin tocar la BD
- "upsert" (default): crea o actualiza como antes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 11:05:58 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 3204671edc fix(ingest_paciente): agregar CORS headers para preflight OPTIONS
Incluye Access-Control-Allow-Headers con X-Lab-Key para que el
navegador pueda hacer el preflight desde RIPS Manager.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 10:56:55 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9651f14302 feat(lab): endpoint server-to-server ingest_paciente para sync desde RIPS
Agrega /api/lab/ingest_paciente.php con autenticación por X-Lab-Key
(LAB_SYNC_KEY en config). Hace UPSERT por numero_documento sin requerir
sesión de admin — permite que RIPS Manager sincronice pacientes directo
a lab_pacientes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 10:48:50 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 f4da864db7 feat(turnero): toma prolongada secuencial + bloqueo muestras/cierre
- ver_formulario_enviado: auto-fill médico (nombres/especialidad/código) en datos_prefilled desde solicitud
- ver_formulario_enviado: canvases de toma progresiva bloqueados secuencialmente — solo el turno activo es firmable, los siguientes aparecen al expirar el countdown
- ver_formulario_enviado: countdown prominente con reloj grande, color dinámico, sonido (Web Audio) y vibración al llegar la hora
- lugar: bloquear cierre del modal durante toma progresiva activa (botón X deshabilitado hasta mp_completar)
- lugar: bloquear Finalizar atención si hay muestras pendientes sin decisión (recibida/rechazada)
- lugar: _syncBtnFinalizar combina consentimientos + muestras para el aviso y estado del botón
- lugar: restricción de usuario a lugar específico via turnero_lugar_id (admin_users) + bloqueo JS en confirmarLugar()
- migrations: turnero_lugar_id en admin_users para restringir bacteriólogos por usuario

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-08 21:16:07 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 233144c017 feat(usuarios): gestión de firma por profesional desde perfil de usuario
Botón firma en tabla de usuarios (verde si ya tiene, gris si no).
Modal con canvas para dibujar o subir imagen, vista previa de firma
actual y opción de eliminar. APIs get/save_firma_usuario.php para admins.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 23:16:26 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 b9bb4fc628 feat(lab_empresas): módulo CRUD de empresas, convenios y tarifas
- Nuevo módulo lab_empresas: lista paginada, modal create/edit empresa,
  gestión de subgrupos inline y CRUD de catálogo lab_tarifas_id
- APIs: empresas.php (list/get/save/toggle/delete),
  empresa_subgrupos.php, tarifas_id.php
- Migración 09 registra el módulo en system_modules y asigna permiso admin

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-04 22:05:14 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 03f02d2788 fix(webhook): skip SSE notification and DB notification for canal=turnero messages
Turnero messages were triggering the SSE event that conversations.php listens to,
causing the contact to flash briefly at the top of the list before disappearing
on the next poll (since get_conversations.php filters them out by canal).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:43:20 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 3f964b424a fix(conversations): filter canal='turnero' out of individual chat message views
get_user_messages.php and get_recent_messages.php now exclude canal='turnero'
so the main bot chat only shows bot messages even for users who also have
turnero conversations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:39:07 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 7eea2ff7ba fix(conversations): exclude canal='turnero' messages from main conversations list
All queries in get_conversations.php now filter (canal IS NULL OR canal='bot')
so the main chat only shows bot conversations and the turnero chat stays isolated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:35:49 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 5acd46df5a fix(turnero): route incoming messages by phone_number_id and fix WhatsAppService canal
- WhatsAppService($canal): when 'turnero', swaps phoneNumberId to whatsapp_phone_number_id_turnero
  so outgoing messages actually go from the turnero number (not the main bot)
- webhook.php: reads metadata.phone_number_id from the payload and compares it to
  whatsapp_phone_number_id_turnero; if it matches, saves canal='turnero' and skips bot processing
- Previously all incoming messages had canal=NULL/bot so Chat Turnero never saw them,
  and all outgoing messages from Chat Turnero were sent via the wrong (main bot) number

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:26:11 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 20146535c7 formularios: agregar botón Clonar para duplicar plantillas
- save_formulario.php: manejo de {clonar:true} → crea copia con "Copia de [nombre]"
- lab_formularios.php: botón icono copy en cada tarjeta + función clonarFormulario()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:21:50 -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 6d63112d76 fix(api): convertir user_id vacío a null antes de guardar paciente
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 09:28:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9e7637582d fix(api): agregar db() helper, corregir requireAuth() en check_whatsapp
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 09:27:03 -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 ae8d2cb13a feat: página pública de verificación de paciente por OTP (SMS)
verificar.php:
- Pública, sin autenticación ni menú lateral
- Diseño moderno: card glassmorphism sobre gradiente brand
- Flujo en 3 pasos con indicador animado
- Paso 1: ingresa cédula → busca paciente
- Paso 2: inputs OTP de 6 dígitos con navegación automática
  y pegado desde portapapeles; cuenta regresiva + reenvío a los 60s
- Paso 3: pantalla de éxito con animación

api/public/send_otp.php:
- Busca paciente por cédula, genera OTP aleatorio de 6 dígitos
- Guarda en lab_otp_tokens con expiración 5 min
- Envía SMS via WEBSms usando config de lab_config
- Retorna teléfono enmascarado (3**1234**67)

api/public/verify_otp.php:
- Valida cedula+codigo contra lab_otp_tokens activos
- Marca OTP como usado y paciente como verificado
  (telefono_verificado=1, verificado_at=NOW())

DB:
- lab_pacientes: +telefono_verificado, +verificado_at
- lab_otp_tokens: tabla nueva para almacenar OTPs temporales

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:39:30 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 21e7c6a836 feat: integración WEBSms en configuración
- Nueva sección WEBSms en lab_configuracion.php con:
  - Switch activo/inactivo (sms_activo)
  - Campo URL base de la API (sms_url)
  - Campo API key / Bearer token (sms_api_key)
  - Campos de prueba: número + mensaje + botón Enviar
- api/lab/test_sms.php: proxy al endpoint POST /api/sms/send
  con Authorization: Bearer, valida respuesta ok/error
- save_config.php: permite guardar sms_url, sms_api_key, sms_activo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 23:27:24 -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 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 Guarnizo 56f30f1c6d fix: firma profesional guarda solo en el campo firmado, no en todos 2026-06-23 19:54:22 -05:00
Lizandro Guarnizo ff8454fa5a up 2026-06-16 16:55:22 -05:00
Lizandro Guarnizo 415ea3ef56 up 2026-06-16 12:06:26 -05:00
Lizandro GuarnizoandClaude Haiku 4.5 d7b1aea5a4 fix: signature fields deduplicate and share across same-type fields
- PHP pre-computes one shared SVG per type (firma/firma_profesional)
- Schema loop skips duplicate firma fields of same type already rendered
- Patient signature from turnero widget propagates to all 'firma' schema fields
- firmar_profesional.php saves nurse signature to ALL firma_profesional fields

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-16 11:41:20 -05:00
Lizandro Guarnizo b317639258 up 2026-05-27 21:39:53 -05:00
Lizandro Guarnizo 2f72d87c3b cambios 2026-05-27 20:40:17 -05:00
Lizandro Guarnizo b8de9ee666 up 2026-05-27 11:44:07 -05:00
Lizandro Guarnizo 313e57aace p 2026-05-27 10:30:47 -05:00
Lizandro Guarnizo 0de3e6e281 up 2026-05-11 14:55:17 -05:00
Lizandro Guarnizo 00232b3513 up 2026-05-11 13:45:36 -05:00
Lizandro Guarnizo f197118acb cambios importates 2026-05-11 12:21:56 -05:00
Lizandro Guarnizo 4bf9d99f8b Update _helpers.php 2026-04-21 16:07:30 -05:00
Lizandro Guarnizo 0164c51c1a up 2026-04-16 23:07:53 -05:00
Lizandro Guarnizo 50b7f7f8ca up 2026-04-16 21:24:01 -05:00
Lizandro Guarnizo c8bef9d9c4 up 2026-04-10 23:04:28 -05:00
Lizandro Guarnizo 5e58b14eba reportes 2026-04-09 16:38:03 -05:00
Lizandro Guarnizo c68a79a3a7 subir mas de un archivo, reprogramados 2026-04-08 10:31:12 -05:00
Lizandro Guarnizo 882ce56e96 multiples documentos 2026-04-08 09:58:08 -05:00
Lizandro Guarnizo db254ca02f direccion 2026-04-08 09:47:47 -05:00
Lizandro Guarnizo d38b5936ca actividades 2026-04-08 09:02:32 -05:00
Lizandro Guarnizo cbf7a8c296 up 2026-04-08 08:31:21 -05:00
Lizandro Guarnizo 4f1b2e146c up 2026-04-07 15:57:53 -05:00
Lizandro Guarnizo ded060e161 lab_formularios 2026-04-07 15:12:22 -05:00
Lizandro Guarnizo 400ff3d615 fix: get_pacientes.php soporta ?id=X para retornar paciente específico con phone_number correcto 2026-04-06 16:45:24 -05:00
Lizandro Guarnizo ca90f79625 up 2026-04-06 12:30:37 -05:00
Lizandro Guarnizo 7956d5431b fix: columna activa → is_active en lab_enfermeras (get_reporte_enfermero) 2026-04-02 11:54:37 -05:00
Lizandro Guarnizo 3516f6e229 fix: permitir crear/editar formularios a roles con permiso write en lab_formularios
- _helpers.php: nueva función requireModuleWrite() que verifica session module_permissions
- save_formulario.php: reemplaza requireAdmin() por requireModuleWrite('lab_formularios')
2026-04-02 10:50:18 -05:00
Lizandro Guarnizo d8ceb3f822 feat: 6 nuevas funcionalidades - notas obligatorias turno, reporte enfermero, plantilla WhatsApp, adjuntar orden modal, roles solo lectura, fix valores copago 2026-04-02 09:41:49 -05:00
Lizandro Guarnizo 3b92f47b54 feat: enlaces de formulario sin vencimiento + PDF descargable sin sesión vía token público 2026-03-25 16:14:26 -05:00
Lizandro Guarnizo 5f695b5604 feat: sistema de notas clínicas para enfermero (ficha + notas libres) y fix lab_reportes métricas 2026-03-25 13:14:25 -05:00
Lizandro Guarnizo 4ba890a0d5 feat: métricas completas, export Excel domicilios con filtros, hora llegada/salida visible 2026-03-25 11:48:24 -05:00