- 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>
- _helpers.php: nueva función requireModuleWrite() que verifica session module_permissions
- save_formulario.php: reemplaza requireAdmin() por requireModuleWrite('lab_formularios')
- conversations.message_id ahora tiene UNIQUE index (aplicado en BD prod)
- saveMessage() usa INSERT IGNORE: si el mismo wamid llega dos veces en
paralelo solo una llamada procesa el mensaje y llama al bot
- La segunda llamada recibe rowCount=0 y hace continue sin pasar al bot
- Elimina race condition que enviaba bienvenida + términos simultáneamente
- index.php: NotificationManager simplificado a stub vacío.
Los elementos notification-bell / global-notification-toasts no existen en el
markup → el setInterval cada 7s solo generaba tráfico inútil a get_notifications.php
Las notificaciones ya se manejan vía SSE en conversations.php
- send_broadcast.php: exponer debug_wamids en respuesta (wamid, wa_status, wa_contact)
para saber exactamente qué devuelve WhatsApp por cada destinatario.
Agregar dryRun log del payload completo al error_log para diagnóstico de
mensajes que WhatsApp acepta (200+wamid) pero no entrega.
La API de WhatsApp NO devuelve {success:true} - devuelve
{messaging_product, messages:[{id:wamid.xxx}], contacts:[...]}.
La comprobación anterior siempre fallaba → sent_count=0, error_count=N.
Ahora verifica presencia de messages/contacts en la respuesta.
- Detecta header_type=IMAGE en get_template_details.php
- send_message (individual): muestra input de imagen si la plantilla lo requiere,
sube a upload_media.php y envía header_image_url al backend
- broadcast (masivo): igual, con upload previo al envío
- api/send_message.php: acepta header_image_url y lo pasa como headerParameters
[type:image, image:{link:URL}] a WhatsAppService::sendTemplateMessage()
- api/send_broadcast.php: igual para cada destinatario del masivo
- Preview en tiempo real de la imagen seleccionada en ambos formularios
- database/07_add_pago_domicilio.sql: 6 columnas nuevas en lab_domicilios
(pago_estado ENUM, pago_modo, pago_monto, pago_fecha, pago_notas, pago_registrado_por)
- Domicilio::filtrarCampos(): permite guardar campos de pago vía actualizar()
- Enfermera::agenda(): incluye valor_domicilio, valor_copago, pago_estado, pago_modo, pago_monto, pago_notas
- api/lab/registrar_pago.php: endpoint POST para registrar/actualizar pago del domicilio
- enfermero_portal.php: bloque cobro en card, modal registrar pago (efectivo/transferencia/exento), objeto pagoModal JS
- lab_domicilios.php: badge pago ⏳/✅/🔵 en fila tabla, sección pago detallada en panel lateral