# 📋 Documentación del Sistema de Laboratorio

Sistema Laboratorio Clínico — Módulos de Agendamiento y Formularios

📅 Última actualización: 30/03/2026 🔢 Versión: 1.0 📦 Módulos: Domicilios · Formularios
🏠

## Módulo 1 — Agendamiento (Domicilios)

Gestión de servicios de toma de muestras a domicilio

### ¿Qué es?

El módulo de agendamiento gestiona los servicios de toma de muestras a domicilio. Permite crear, asignar, seguir y completar visitas médicas domiciliarias. Los administradores gestionan la agenda desde `lab_domicilios.php`; los enfermeros gestionan su propia agenda desde `enfermero_portal.php`.

### Archivos involucrados

Archivo | Descripción
--- | ---
`lab_domicilios.php` | Vista principal del admin — tabla con filtros, detalle del domicilio, formularios recibidos, exportar CSV
`enfermero_portal.php` | Portal exclusivo del enfermero — su agenda personal del día, ordenada por hora, con tarjetas colapsables
`lab_enfermeras.php` | CRUD del personal de enfermería
`classes/lab/Domicilio.php` | Clase ORM — crear, editar, cambiar estado, estadísticas
`classes/lab/Enfermera.php` | Clase ORM — CRUD, agenda por enfermero, carga de trabajo
`classes/lab/Asignacion.php` | Clase ORM — asignar / reasignar / liberar enfermero a domicilio
`api/lab/get_domicilios.php` | GET — lista de domicilios con filtros y estadísticas del día
`api/lab/save_domicilio.php` | POST — crear, actualizar o cambiar estado
`api/lab/update_domicilio_enfermero.php` | POST — el enfermero avanza el estado desde su portal
`api/lab/my_agenda.php` | GET — agenda del enfermero actualmente autenticado
`api/lab/save_asignacion.php` | POST — asignar o reasignar enfermero
`api/lab/get_asignaciones.php` | GET — asignaciones por fecha
`api/lab/registrar_pago.php` | POST — registrar pago de un domicilio
`api/lab/save_servicio_extra.php` | POST — agregar servicio realizado durante la visita
`api/lab/get_notas_domicilio.php` | GET — notas clínicas y libres del domicilio
`api/lab/upload_nota_imagen.php` | POST — subir imagen adjunta a una nota
`api/lab/crear_desde_whatsapp.php` | GET/POST — crear paciente u orden desde una conversación de WhatsApp activa

### Base de datos

#### Tabla `lab_domicilios`

Tabla principal. Cada fila es un servicio a domicilio.

Campo | Tipo | Descripción
--- | --- | ---
`id` | INT PK | Identificador único
`paciente_id` | INT FK | Paciente al que se le realiza el servicio
`orden_id` | INT FK NULL | Orden médica adjunta (opcional)
`direccion` | TEXT | Dirección completa de la visita
`ciudad` | VARCHAR(100) | Ciudad
`barrio` | VARCHAR(100) | Barrio
`indicaciones_dir` | TEXT | Referencias o indicaciones adicionales ("apto 302, tocar campanilla")
`fecha_programada` | DATE | Fecha de la visita
`hora_programada` | TIME | Hora de la visita
`tipo_servicio` | VARCHAR(100) | Tipo de servicio (toma de muestra, etc.)
`tipo_cliente` | ENUM | `particular` / `seguro` / `eps`
`examenes_solicitados` | TEXT | Lista de exámenes (cuando no hay orden médica)
`seguro_nombre` | VARCHAR | Nombre del seguro o EPS
`autorizacion` | VARCHAR | Número de autorización
`valor_domicilio` | DECIMAL | Valor del servicio nullable
`valor_copago` | DECIMAL | Copago a cargo del cliente nullable
`copago_laboratorio` | DECIMAL | Copago al laboratorio nullable
`pago_estado` | ENUM | `pendiente` / `pagado` / `exento`
`pago_modo` | ENUM | `efectivo` / `transferencia` / `otro`
`pago_monto` | DECIMAL | Monto pagado
`pago_fecha` | DATETIME | Fecha del pago
`pago_notas` | TEXT | Notas sobre el pago
`estado` | ENUM | Ver flujo de estados
`motivo_cancelacion` | TEXT | Motivo si fue cancelado (obligatorio al cancelar)
`fecha_reprogramada` | DATE | Nueva fecha si fue reprogramado
`hora_llegada` | TIME | Registrada automáticamente al iniciar la visita
`hora_salida` | TIME | Registrada automáticamente al completar
`observaciones` | TEXT | Observaciones del resultado de la visita
`muestras_tomadas` | TEXT | Lista de muestras obtenidas
`notas_admin` | TEXT | Notas internas del equipo administrativo
`creado_por` | INT FK | Usuario que creó el registro

#### Tabla `lab_enfermeras`

Personal de enfermería disponible para asignación.

Campos | Descripción
--- | ---
`id`, `numero_documento` | PK e identificador del empleado
`tipo_documento` | CC / CE / TI / PA
`nombre_completo`, `telefono`, `telefono_alt` | Datos de contacto
`email`, `zona`, `notas` | Información adicional
`is_active` | Soft-delete del registro

#### Tabla `lab_asignaciones`

Asignación de enfermero a domicilio. Máximo un enfermero activo por domicilio (`UNIQUE KEY` en `domicilio_id`).

Campo | Descripción
--- | ---
`id`, `domicilio_id`, `enfermera_id` | PK y relaciones
`asignada_por` | Usuario admin que realizó la asignación
`estado` | `asignada` / `confirmada` / `liberada` / `completada`
`notas` | Observaciones de la asignación

#### Tabla `lab_servicios_extra`

Servicios realizados por el enfermero durante la visita, adicionales a la orden original.

Campo | Descripción
--- | ---
`tipo` | `inyeccion` / `cura` / `nebulizacion` / `toma_muestra` / `tension_arterial` / `glucometria` / `otro`
`descripcion`, `notas` | Detalle del servicio
`requiere_pago`, `valor` | Si genera cobro adicional y su valor
`realizado_por` | FK al enfermero que lo realizó

#### Tabla `lab_domicilio_notas`

Notas registradas por el enfermero durante la visita. Dos tipos:

🩺 clinica Ficha clínica: antecedentes, medicamentos, acudiente (si es menor de edad).
📝 libre Nota libre con título, cuerpo de texto enriquecido e imagen adjunta.

Campos | Descripción
--- | ---
`id`, `domicilio_id`, `enfermera_id` | PK y relaciones
`tipo` | `clinica` / `libre`
`antecedentes`, `medicamentos` | Sección clínica
`acudiente_nombre`, `acudiente_documento` | Datos del acudiente si el paciente es menor
`titulo`, `cuerpo`, `imagen_path` | Sección de nota libre

### Roles y permisos

#### 🛡️ Admin

- Crear, editar y ver todos los domicilios
- Asignar / reasignar enfermeros
- Registrar pagos
- Exportar Excel
- Ver informe completo con notas
- Ver agenda de cualquier enfermero con `?eid=X`

#### 👩‍⚕️ Enfermero

- Solo ve su propia agenda en `enfermero_portal.php`
- Avanza el estado de sus domicilios asignados
- Agrega servicios extra
- Registra notas clínicas y libres
- Visualiza órdenes médicas adjuntas

⚠️ Redirección automática: si el usuario autenticado tiene rol `enfermero`, `lab_domicilios.php` lo redirige inmediatamente a `enfermero_portal.php`.

### Flujo de estados

programado
→
confirmado
→
en_camino
→
en_domicilio
→
completado
⛔ cancelado
🔄 reprogramado
← Posibles desde cualquier estado activo

Notas automáticas según estado:

Evento | Acción automática
--- | ---
Transición a `en_domicilio` | Se registra `hora_llegada` automáticamente
Transición a `completado` | Se registra `hora_salida` automáticamente
Transición a `cancelado` | Campo `motivo_cancelacion` obligatorio
Transición a `reprogramado` | Campo `fecha_reprogramada` obligatorio

Transiciones permitidas al enfermero (validadas en `update_domicilio_enfermero.php`):

Estado actual | Estados posibles
--- | ---
programado | confirmado
confirmado | en_camino · cancelado
en_camino | en_domicilio · cancelado
en_domicilio | completado · cancelado

El admin puede cambiar a cualquier estado directamente, incluyendo cancelar desde cualquier punto.

### Funcionalidades

🔍 FiltrosPor fecha, estado y enfermero. Botón "Hoy" para filtro rápido.
📊 Resumen del díaConteo de domicilios por estado en la parte superior.
📋 Panel de detalleAbre al hacer clic: info completa, notas clínicas e informe imprimible.
👥 Asignar enfermeroModal con lista del personal disponible. Incluye reasignación.
⚠️ Sin asignarBadge con conteo de domicilios sin enfermero asignado.
💰 Registrar pagoModal para marcar cobro con modalidad y monto.
➕ Servicios extraEl enfermero los agrega desde su portal durante la visita.
🩺 Notas del enfermeroFicha clínica y notas libres con imagen adjunta.
📄 Informe imprimibleVista imprimible con datos del paciente, ficha clínica y notas.
📁 Exportar CSV / ExcelIncluye columnas de notas del enfermero.
📝 Formularios recibidosPestaña que muestra formularios enviados con filtros.
📱 Portal del enfermeroTarjetas colapsables, separadas en Activos y Finalizados.

### API Endpoints

Endpoint | Método | Descripción
--- | --- | ---
`api/lab/get_domicilios.php` | GET | Lista con filtros. `?id=X` para uno solo con detalle completo.
`api/lab/save_domicilio.php` | POST | Crear, editar o cambiar estado. Con `solo_estado=true` solo cambia el estado.
`api/lab/update_domicilio_enfermero.php` | POST | El enfermero avanza el estado de su domicilio.
`api/lab/my_agenda.php` | GET | Agenda del enfermero autenticado con servicios extra.
`api/lab/save_asignacion.php` | POST | Asignar o reasignar enfermero a domicilio.
`api/lab/get_asignaciones.php` | GET | Asignaciones por fecha.
`api/lab/registrar_pago.php` | POST | Registrar pago con monto y modalidad.
`api/lab/save_servicio_extra.php` | POST | Agregar servicio realizado durante la visita.
`api/lab/get_notas_domicilio.php` | GET | Notas del domicilio (clínicas y libres).
`api/lab/upload_nota_imagen.php` | POST | Subir imagen adjunta a una nota libre.
`api/lab/crear_desde_whatsapp.php` | GET/POST | Crear paciente u orden desde una conversación de WhatsApp activa.

📝

## Módulo 2 — Formularios

Builder visual, envío por WhatsApp, firma digital y sello SHA-256

### ¿Qué es?

El módulo de formularios permite crear plantillas de documentos (consentimientos, historias clínicas, autorizaciones, encuestas) mediante un builder visual, enviarlas a los pacientes por WhatsApp y recopilar sus respuestas con firma digital. El documento firmado genera un sello de integridad SHA-256 que puede verificarse públicamente.

### Archivos involucrados

Archivo | Descripción
--- | ---
`lab_formularios.php` | Vista principal — lista de plantillas y registro de envíos
`lab_formulario_builder.php` | Editor visual drag & drop (ventana separada, solo admin)
`form_cliente.php` | Página pública — el paciente llena y firma sin iniciar sesión
`ver_formulario_enviado.php` | Vista del documento firmado — acceso por ID (admin/enfermero) o token (cliente)
`verificar_formulario.php` | Verificación pública de autenticidad por hash SHA-256
`classes/lab/Formulario.php` | Clase ORM — CRUD de plantillas, crear envíos, guardar respuestas, generar hash
`api/lab/get_formularios.php` | GET — lista plantillas o envíos
`api/lab/save_formulario.php` | POST — crear, editar y eliminar plantillas (solo admin)
`api/lab/send_formulario.php` | POST — crear instancia de envío, devolver URL pública y mensaje WhatsApp
`api/lab/submit_formulario.php` | GET/POST — cargar el formulario por token / guardar la respuesta del cliente
`api/lab/firmar_profesional.php` | POST — guardar firma del profesional (requiere sesión activa)

### Base de datos

#### Tabla `lab_formularios`

Plantillas de documentos creadas desde el builder.

Campo | Tipo | Descripción
--- | --- | ---
`id` | INT PK | Identificador único
`nombre` | VARCHAR(150) | Nombre de la plantilla
`descripcion` | TEXT | Descripción visible al cliente
`categoria` | ENUM | `consentimiento` / `historia_clinica` / `autorizacion` / `encuesta` / `otro`
`esquema` | LONGTEXT | JSON con el array de campos del formulario
`permite_firma` | TINYINT(1) | El formulario tiene sección de firma global
`requiere_firma` | TINYINT(1) | La firma global es obligatoria
`firma_modos` | VARCHAR(50) | `canvas`, `foto` o `canvas,foto` (separados por coma)
`version` | SMALLINT | Se incrementa automáticamente al editar el esquema
`is_active` | TINYINT(1) | Soft-delete
`creado_por` | INT FK | Usuario que creó la plantilla
`doc_encabezado` | VARCHAR | Override del nombre de empresa en el documento
`doc_subtitulo` | VARCHAR | Override del subtítulo en el documento
`doc_logo_base64` | LONGTEXT | Override del logo en el documento
`doc_color` | VARCHAR(20) | Override del color del encabezado del documento
`doc_pie_pagina` | TEXT | Override del pie de página

#### Tabla `lab_form_envios`

Cada fila es una instancia enviada a un paciente.

Campo | Tipo | Descripción
--- | --- | ---
`id` | INT PK | Identificador único
`formulario_id` | INT FK | Plantilla enviada
`paciente_id` | INT FK NULL | Paciente asociado
`domicilio_id` | INT FK NULL | Domicilio asociado (opcional)
`token` | CHAR(64) UNIQUE | Token público — 64 chars hex (acceso sin sesión)
`datos_prefilled` | LONGTEXT | JSON con datos pre-llenados al enviar (incluye `__paciente.*`)
`datos_cliente` | LONGTEXT | JSON con las respuestas completadas por el cliente
`firma_svg` | LONGTEXT | Firma del paciente (PNG base64 — canvas o foto)
`ip_cliente` | VARCHAR(45) | IP del cliente al enviar el formulario
`user_agent` | VARCHAR(512) | Navegador del cliente
`estado` | ENUM | `pendiente` / `completado` / `firmado` / `expirado`
`enviado_por` | INT FK | Usuario que generó el enlace
`enviado_via` | ENUM | `whatsapp` / `email` / `link`
`expira_en` | DATETIME NULL | Siempre `NULL` — el enlace no expira
`completado_en` | DATETIME | Fecha y hora en que el cliente completó el formulario
`hash_verificacion` | CHAR(64) | Sello de integridad SHA-256 del documento

### Roles y permisos

#### 🛡️ Admin

- Crear, editar y eliminar plantillas en el builder
- Enviar formularios a cualquier paciente
- Ver todos los envíos
- Descargar PDF de cualquier formulario

#### 👩‍⚕️ Enfermero

- Enviar formularios existentes a sus pacientes
- Ver solo sus propios envíos (`enviado_por = su user_id`)
- No puede crear ni editar plantillas
- Puede firmar como profesional en formularios que él mismo envió

#### 🌐 Cliente (público)

- Accede a `form_cliente.php?t=TOKEN` sin autenticación
- Llena y firma el formulario
- Puede volver al mismo enlace para ver el documento firmado
- Puede descargarlo como PDF

### Flujo completo

1. Admin crea la plantilla
   Abre `lab_formulario_builder.php` (ventana nueva), arrastra campos al canvas, configura diseño del documento (logo, color, encabezado, pie de página) y guarda → POST `api/lab/save_formulario.php`.
2. Admin o Enfermero envía el formulario
   Desde `lab_formularios.php` → botón "Enviar" → selecciona paciente → elige canal (WhatsApp o solo link) → POST `api/lab/send_formulario.php`. Se genera un token de 64 chars (`bin2hex(random_bytes(32))`) y se crea la fila en `lab_form_envios` con `estado = pendiente`.
3. Cliente recibe el enlace
   Abre `form_cliente.php?t=TOKEN` → GET `api/lab/submit_formulario.php?t=TOKEN` carga los datos. Si ya fue firmado → muestra pantalla de solo lectura con link al PDF.
4. Cliente llena el formulario
   Campos "linked" llegan pre-llenados con datos del paciente (readonly si tienen valor, editables si están vacíos). Los campos `firma_profesional` muestran aviso "uso exclusivo del profesional". El cliente dibuja su firma o adjunta una foto.
5. Cliente envía
   POST `api/lab/submit_formulario.php` → se genera hash SHA-256 (contenido + firma + ID + token + timestamp) → estado cambia a `firmado` (con firma) o `completado` (sin firma). Pantalla de éxito con hash visible y botón para descargar el PDF.
6. Profesional firma (si el formulario lo requiere)
   Admin/Enfermero abre `ver_formulario_enviado.php?id=X` con sesión activa, dibuja su firma en el canvas del campo `firma_profesional` → POST `api/lab/firmar_profesional.php`.
7. Admin/Enfermero revisa el resultado
   `lab_formularios.php` → pestaña "Envíos" → icono "Ver respuesta" → `ver_formulario_enviado.php?id=X` — documento HTML imprimible.
8. Verificación pública de integridad
   `verificar_formulario.php?h=HASH_SHA256` → busca en `hash_verificacion` → muestra nombre del formulario, paciente, fecha, estado y si el sello es válido.

### Tipos de campos del Builder

#### Campos de entrada

Tipo | Descripción
--- | ---
`texto` | Campo de texto corto de una sola línea
`textarea` | Área de texto largo (varias líneas)
`numero` | Campo numérico
`fecha` | Selector de fecha
`hora` | Selector de hora
`select` | Lista desplegable con opciones configurables
`radio` | Selección única con opciones configurables
`checkbox` | Selección múltiple con opciones configurables
`lista_marcable` | Lista de ítems numerados con checkboxes

#### Campos de firma

Tipo | Descripción
--- | ---
`firma` | Firma del paciente — visible y editable en `form_cliente.php`
`firma_profesional` | Firma del profesional — bloqueada para el cliente; solo editable desde el panel admin/enfermero

#### Campos de contenido

Tipo | Descripción
--- | ---
`separador` | Separador visual o título de sección
`parrafo` | Bloque de texto estático (pre-formatado o flujo libre)
`parrafo_inline` | Párrafo con marcadores `{nombre_completo}`, `{telefono}`, etc. que se convierten en espacios editables si el valor está vacío

#### Campos vinculados al paciente (`tipo: linked`)

Se auto-rellenan con los datos del paciente al momento de enviar. Si el valor existe → campo de solo lectura. Si está vacío → el cliente puede completarlo.

`linked_key` | Dato que extrae
--- | ---
`nombre_completo` | Nombre completo del paciente
`numero_documento` | Número de documento
`tipo_documento` | Tipo de documento
`fecha_nacimiento` | Fecha de nacimiento
`telefono` | Teléfono
`email` | Correo electrónico
`eps` | EPS o aseguradora
`direccion` | Dirección

### Firma digital

Modo | Funcionamiento
--- | ---
canvas | El cliente dibuja su firma con el dedo o el mouse. Se captura con `canvas.toDataURL('image/png')`.
foto | El cliente sube una imagen desde su cámara o galería (`<input accept="image/*" capture="environment">`). Se convierte a base64 con `FileReader`.

Ambos modos pueden estar activos simultáneamente en la misma plantilla configurando `firma_modos = "canvas,foto"`.

Firma global vs. firma por campo:
Si el esquema no incluye campos tipo `firma`, se muestra una sección de firma global al pie del formulario. Si el esquema incluye campos `firma`, cada uno tiene su propio widget canvas en la posición configurada.

### Enlace público y vigencia

🔗 URL pública `form_cliente.php?t=TOKEN`
🔑 Token64 chars hex — `bin2hex(random_bytes(32))`
🔓 Sin sesiónNo requiere cuenta ni iniciar sesión
♾️ Sin vencimiento `expira_en` siempre es `NULL`
🔒 Bloqueo por estadoSi ya fue firmado → solo lectura, no permite modificar
🔁 IdempotenciaSi el cliente reintenta enviar, devuelve éxito sin duplicar

### PDF y visualización del documento

✅ Sin librerías de PDF: el documento es la página `ver_formulario_enviado.php` con estilos `@media print`. El usuario imprime o guarda como PDF directamente desde el navegador.

Contenido del documento impreso:

- Encabezado con logo, nombre, subtítulo, datos de contacto y color corporativo
- Datos del paciente (nombre, documento, fecha de nacimiento, teléfono, EPS)
- Respuestas del formulario campo por campo en el orden del esquema
- Imagen de la firma del paciente
- Firma del profesional (si fue completada)
- Sello SHA-256 con link para verificar autenticidad
- Pie de página con fecha de generación e ID del documento

Formas de acceder al documento:

URL | Quién puede acceder
--- | ---
`ver_formulario_enviado.php?id=X` | Admin (cualquier formulario) o Enfermero (solo los que él envió). Requiere sesión.
`ver_formulario_enviado.php?t=TOKEN` | Cliente u cualquier persona con el enlace. Sin sesión. Solo si el estado es `firmado` o `completado`.

### Sello de integridad SHA-256

Al guardar la respuesta del cliente, el sistema genera un hash SHA-256 que vincula de forma única el contenido del formulario con la firma y el momento en que se completó.

Construcción del hash (en `Formulario::guardarRespuesta()`):

    SHA-256 de:
      JSON de los datos del cliente
      + firma SVG/PNG del paciente
      + ID interno del envío
      + token del enlace
      + timestamp del momento de registro

¿Para qué sirve? Cualquier persona con el hash puede ir a `verificar_formulario.php?h=HASH` para confirmar que el documento existe, el nombre del formulario y del paciente, la fecha en que fue completado y el estado actual. Si el documento fue alterado, el hash no coincidirá y la verificación fallará.

### Firma del profesional

1. Al diseñar la plantilla en el builder se agrega un campo `tipo: firma_profesional` en la posición deseada.
2. Cuando el cliente llena el formulario, ese campo muestra solo un aviso: "Uso exclusivo del profesional de salud". El cliente no puede interactuar con él.
3. Una vez que el cliente ha completado y enviado, el admin o enfermero abre `ver_formulario_enviado.php?id=X` con sesión activa y verá el canvas de firma en esa posición.
4. El profesional dibuja su firma y hace clic en "Guardar firma" → POST `api/lab/firmar_profesional.php`.

Validaciones en el servidor:

- Requiere sesión activa (`isUserLoggedIn()`)
- Si el usuario es enfermero, solo puede firmar en formularios que él mismo envió
- Valida que el `campo_id` corresponde a un campo `tipo: firma_profesional` en el esquema
- Valida que la imagen enviada sea un data URI de imagen válido (prevención XSS/inyección)

Si el formulario se accede via `?t=TOKEN` (cliente público), el canvas no aparece. En su lugar se muestra un aviso "Pendiente de firma del profesional" (solo visible en pantalla, no en el PDF impreso).

### API Endpoints

Endpoint | Método | Autenticación | Descripción
--- | --- | --- | ---
`api/lab/get_formularios.php` | GET | Sesión | Lista plantillas. `?id=X` para una sola. `?envios=1` para lista de envíos.
`api/lab/save_formulario.php` | POST | Admin | Crear, editar o eliminar una plantilla.
`api/lab/send_formulario.php` | POST | Sesión | Crear instancia de envío. Devuelve URL pública y mensaje para WhatsApp.
`api/lab/submit_formulario.php` | GET | Público | Cargar el formulario por token (sin sesión).
`api/lab/submit_formulario.php` | POST | Público | Guardar la respuesta y firma del cliente.
`api/lab/firmar_profesional.php` | POST | Sesión | Guardar la firma del profesional en un campo `firma_profesional`.

Documentación generada para uso interno del equipo · 30/03/2026

🛡️

## Manual de Uso — Administrador · Domicilios

🛡️ Admin Gestión completa desde `lab_domicilios.php`

### Crear un nuevo domicilio

1

##### Abrir el formulario

Haz clic en el botón ＋ Nuevo Domicilio ubicado en la esquina superior derecha de la pantalla. Se abrirá un modal con el formulario de creación.

2

##### Buscar y seleccionar el paciente

En el campo Paciente, empieza a escribir el nombre o documento del paciente. Aparecerá un listado de sugerencias; haz clic en el paciente correcto para seleccionarlo.

✅ El paciente debe existir previamente en el sistema. Si no aparece, créalo primero desde `lab_pacientes.php`.
3

##### Llenar los datos del servicio

Completa los campos requeridos (*):

- Dirección completa — incluye barrio e indicaciones adicionales si aplica
- Fecha programada — se pre-llena con la fecha del filtro activo
- Tipo de servicio — ej: "toma de muestras", "inyección"
- Tipo de cliente — si estás en Seguro / EPS, aparecerá el campo del nombre del seguro
- Valores de cobro — valor domicilio y/o copago (dejar vacío si no aplica)

4

##### Adjuntar orden médica (opcional)

Si tienes una imagen o PDF con la orden del médico, haz clic en 📎 Adjuntar orden. Se acepta JPG, PNG, PDF y DOC hasta 10 MB.

5

##### Guardar

Haz clic en 💾 Guardar. El domicilio aparecerá en la tabla con estado programado.

### Asignar un enfermero

1

##### Seleccionar el domicilio

Haz clic en la fila del domicilio en la tabla. Se abrirá el panel de detalle a la derecha. Si el domicilio no tiene enfermero, verás un aviso en naranja: "Sin enfermero asignado".

2

##### Abrir el modal de asignación

Haz clic en 👤 Asignar (o Reasignar si ya tiene uno). Se abrirá un modal con la lista del personal disponible.

3

##### Seleccionar y confirmar

En el desplegable elige el enfermero. Verás cuántos domicilios tiene asignados hoy y su usuario de acceso al portal. Haz clic en ✔ Confirmar asignación.

✅ Una vez asignado, el enfermero verá este domicilio en su portal al ingresar.

### Cambiar el estado de un domicilio

Los botones de avance de estado aparecen en el panel de detalle del domicilio seleccionado:

programado → Confirmar → En camino → En domicilio → Completar
1

##### Seleccionar el domicilio y hacer clic en el botón de estado

En el panel de detalle aparecerán uno o dos botones según el estado actual. Haz clic en el que corresponda y confirma en el diálogo que aparece.

⚠️ Al cambiar a cancelado el sistema pedirá un motivo de cancelación. Este campo es obligatorio.
✅ Los estados en_domicilio (hora llegada) y completado (hora salida) registran la hora automáticamente si el enfermero realiza la transición desde su portal.

### Registrar un pago

1

##### Domicilio con valores de cobro

En el panel de detalle, si el domicilio tiene Valor domicilio o Copago asignados, verás la sección de cobro con un badge ⏳ Pago pendiente.

2

##### Abrir el registro de pago

Haz clic en el botón 💳 Registrar pago dentro del bloque de cobro.

3

##### Completar los datos del pago

Selecciona la modalidad (💵 Efectivo / 📲 Transferencia / 📋 Otro), ingresa el monto recibido y agrega notas si es necesario. Haz clic en Confirmar pago.

✅ Si el servicio es para un cliente con seguro y no genera cobro directo, selecciona Exento desde las opciones de pago_estado.

### Filtros y exportar a Excel

Control | Descripción
--- | ---
📅 Fecha | Filtra los domicilios por fecha programada. Se carga con la fecha actual al abrir la pantalla.
Estado | Filtra por estado del domicilio. Deja en blanco para ver todos.
Enfermero | Filtra solo los domicilios asignados a ese enfermero.
📅 Hoy | Restablece el filtro de fecha a la fecha de hoy.
📁 Excel | Exporta todos los domicilios que coincidan con los filtros activos, incluyendo notas del enfermero.

✅ Los cambios en los filtros se aplican automáticamente sin necesidad de hacer clic en un botón de buscar.
👩‍⚕️

## Manual de Uso — Enfermero · Portal

👩‍⚕️ Enfermero Gestión de agenda personal desde `enfermero_portal.php`

### Acceder al portal

1

##### Iniciar sesión

Ve a `login.php` e ingresa con el usuario y contraseña que el administrador te asignó. El sistema te redirigirá automáticamente a `enfermero_portal.php`.

✅ Si intentas acceder a otra sección del sistema, serás redirigido de vuelta a tu portal automáticamente.
2

##### Ver tu agenda del día

Encontrarás dos bloques: Activos (domicilios pendientes de hoy) y Finalizados (completados o cancelados). Cada domicilio aparece como una tarjeta colapsable ordenada por hora.

### Avanzar el estado de un domicilio

1

##### Expandir la tarjeta

Haz clic en la tarjeta del domicilio para expandirla y ver el detalle completo: paciente, dirección, hora, orden médica adjunta y botones de acción.

2

##### Usar el botón de estado correspondiente

Estado actual | Botón disponible | ¿Qué ocurre?
--- | --- | ---
programado | ✔ Confirmar | Confirmas que realizarás la visita
confirmado | 🚗 En camino | Indicas que saliste hacia el domicilio
en_camino | 🏠 En domicilio | Indicas que llegaste — se registra la hora de llegada automáticamente
en_domicilio | ✅ Completar | Finalizas la visita — se registra la hora de salida automáticamente

⚠️ Si necesitas cancelar un domicilio, deberás ingresar el motivo. Consulta con el administrador si tienes dudas sobre cuándo cancelar.

### Registrar notas clínicas y libres

1

##### Ficha clínica del paciente

Dentro de la tarjeta del domicilio, busca la sección Ficha clínica. Puedes registrar:

- Antecedentes — patologías previas del paciente
- Medicamentos — medicamentos que toma actualmente
- Acudiente — nombre y documento del acudiente si el paciente es menor de edad

2

##### Nota libre

Haz clic en ＋ Agregar nota. Puedes escribir un título, el cuerpo de la nota y adjuntar una imagen (por ejemplo, una foto del estado del paciente o de las muestras tomadas).

✅ Las notas quedan visibles para el administrador en el panel de detalle y en el informe imprimible del domicilio.

### Agregar servicios extra

1

##### ¿Cuándo usar esto?

Si durante la visita realizas servicios adicionales a los de la orden original (ej: una inyección, una curación, toma de tensión arterial), puedes registrarlos para que queden en el historial.

2

##### Agregar el servicio

En la tarjeta del domicilio, haz clic en ＋ Servicio extra. Selecciona el tipo, agrega una descripción y, si genera cobro adicional, marca la opción Requiere pago e ingresa el valor.

Tipo disponible | Descripción
--- | ---
`inyeccion` | Administración de medicamento inyectable
`cura` | Curación de herida o procedimiento de limpieza
`nebulizacion` | Terapia de nebulización
`toma_muestra` | Toma de muestra adicional
`tension_arterial` | Medición de tensión arterial
`glucometria` | Medición de glucosa en sangre
`otro` | Cualquier otro procedimiento (especificar en descripción)

📋

## Manual de Uso — Administrador · Formularios

🛡️ Admin 👩‍⚕️ Enfermero (envío) Desde `lab_formularios.php`

### Crear una plantilla de formulario

Solo el Admin puede crear y editar plantillas. Los enfermeros solo pueden enviar formularios existentes.
1

##### Ir al builder

Desde `lab_formularios.php`, haz clic en ＋ Nueva plantilla. Se abrirá el editor `lab_formulario_builder.php` en una ventana nueva.

2

##### Configurar el encabezado del documento

En el panel derecho del builder puedes personalizar: nombre de la empresa, subtítulo, logo (imagen base64), color del encabezado y pie de página. Estos datos aparecerán en el PDF imprimible.

3

##### Agregar campos al formulario

Arrastra campos del panel izquierdo al canvas central. Tipos disponibles:

Texto Textarea Número Fecha / Hora Select Radio Checkbox Lista marcable Vinculado al paciente Párrafo inline Firma paciente Firma profesional
4

##### Configurar la firma

En la sección Firma del builder puedes activar los modos permitidos: ✍️ Canvas (dibujo) y/o 📷 Foto. Si la firma es obligatoria, marca Requerida.

5

##### Guardar la plantilla

Haz clic en 💾 Guardar. La plantilla quedará disponible en `lab_formularios.php` para ser enviada a pacientes.

✅ Cada vez que edites el esquema de campos, la versión de la plantilla se incrementa automáticamente.

### Enviar un formulario a un paciente

1

##### Seleccionar la plantilla y hacer clic en Enviar

En `lab_formularios.php` busca la plantilla que deseas enviar y haz clic en el botón 📤 Enviar. Se abrirá un modal.

2

##### Buscar y seleccionar el paciente

Empieza a escribir el nombre o documento del paciente. Al seleccionarlo, verás una vista previa de los campos que se pre-llenarán automáticamente con sus datos.

3

##### Elegir el canal de envío

Selecciona cómo compartirás el enlace:

- WhatsApp — genera un mensaje pre-redactado con el enlace listo para enviar desde en la conversación del paciente
- Solo link — copia el enlace y compártelo como prefieras

4

##### Confirmar el envío

Haz clic en Generar enlace. Se creará un token único para ese paciente. El enlace generado no tiene fecha de vencimiento y es de un solo uso (no permite modificar la respuesta una vez enviada).

✅ El enlace funciona sin que el paciente necesite crear cuenta ni iniciar sesión.

### Revisar las respuestas de un formulario

1

##### Ir a la pestaña de envíos

En `lab_formularios.php`, haz clic en la pestaña 📋 Envíos. Verás el historial de todos los formularios enviados con su estado actual.

⏳ pendiente ✅ completado ✍️ firmado ❌ expirado
2

##### Ver la respuesta del paciente

En formularios con estado completado o firmado, aparecerá el botón 👁 Ver. Este abrirá un modal con todas las respuestas campo por campo y la imagen de la firma.

3

##### Descargar el PDF

Haz clic en el ícono 🖨️ junto al botón Ver, o en el botón Ver / Imprimir PDF dentro del modal. Esto abre `ver_formulario_enviado.php` con el documento completo listo para imprimir o guardar como PDF.

### Firmar como profesional

⚠️ Esta opción solo aplica cuando la plantilla tiene un campo firma_profesional en su diseño.
1

##### Abrir el formulario completado

Ve a `ver_formulario_enviado.php?id=X` con tu sesión activa (admin o el enfermero que lo envió). Verás el documento con el canvas de firma del profesional en la posición configurada.

✅ Si el paciente aún no ha completado el formulario, el canvas de firma profesional no aparecerá hasta que lo complete.
2

##### Dibujar la firma y guardar

Dibuja tu firma en el canvas usando el mouse o la pantalla táctil. Haz clic en 💾 Guardar firma. La firma quedará vinculada al documento de forma permanente.

### Verificar la autenticidad de un documento

1

##### Obtener el hash SHA-256 del documento

Al pie del documento en `ver_formulario_enviado.php` encontrarás el sello de integridad — una cadena hexadecimal de 64 caracteres. Este hash identifica únicamente este documento.

2

##### Ir al verificador público

Accede a `verificar_formulario.php?h=HASH_AQUI` o comparte ese enlace con la persona que necesita verificar la autenticidad. El sistema mostrará:

- Nombre del formulario y del paciente
- Fecha en que fue completado
- Estado actual del documento
- Confirmación de que el sello es válido ✅ o inválido ❌

✅ Esta verificación es pública — cualquier persona con el hash puede usarla sin necesidad de tener cuenta en el sistema.

Manual de uso — Sistema de Laboratorio · 30/03/2026