Files
whatsapp/modules/soporte/docs/arquitectura/60-decisiones-y-deuda.md
Lizandro GuarnizoandClaude Opus 5 fe96e5b60d Documentación en usted, y panel de LIA con el mismo diseño del dashboard
Toda la documentación pasa de voseo a tratamiento de usted, incluidos los
diagramas y los textos de la interfaz. Los prompts de ambos asistentes lo
piden explícitamente, para que las respuestas generadas también lo respeten.

El panel de LIA en la página de documentación adopta el diseño del dashboard
del turnero: mismo botón circular, mismo panel deslizante con encabezado en
degradado y logo LIA, mismos chips de atajo, burbujas y campo de entrada.
Los atajos se arman con los documentos que ese usuario puede ver.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 10:57:28 -05:00

4.6 KiB

Decisiones y deuda técnica

Por qué el sistema es como es, y qué cosas conviene saber antes de tocarlo.

Decisiones tomadas a propósito

Migración gradual, sin corte

Conviven el sistema original (archivos en la raíz) y el nuevo (módulos). No hubo una reescritura de golpe.

Por qué: el laboratorio opera todos los días. Una reescritura completa implicaba congelar el desarrollo o mantener dos sistemas en paralelo.

Costo: hay que saber en cuál de los dos está el código de cada pantalla. Los lab_* suelen estar en la raíz; el turnero está en el módulo.

Sin framework de frontend

Las vistas son PHP que emiten HTML, con JavaScript embebido en la misma vista.

Por qué: despliegue por git pull, sin build ni compilación. Un archivo se edita y ya está en producción.

Costo: hay código repetido entre vistas, y las vistas grandes (el turnero) pasan de las 2.000 líneas.

Esquemas de formulario en JSON

Los formularios se definen en JSON dentro de lab_formularios.esquema, no en tablas normalizadas.

Por qué: las fichas clínicas cambian seguido y cada una tiene campos distintos. Normalizarlas obligaba a migrar el esquema con cada formulario nuevo.

Costo: no se puede consultar por SQL «todos los pacientes con fiebre». Las respuestas viven dentro de un JSON.

La identidad de quien firma se resuelve en el servidor

Nunca se acepta del navegador quién firmó algo.

Por qué: es un dato con valor legal. Un cliente puede mentir; la sesión no.

El turno original nunca se modifica

Cuando una muestra pendiente se completa en una visita posterior, el turno original queda como estaba. Solo se registra el vínculo.

Por qué: el turno cerrado es un registro histórico. Alterarlo retroactivamente falsea los tiempos de atención y la facturación de aquel día.

Inventarios generados, no escritos

Las tablas de módulos, endpoints, tablas y roles de esta documentación se leen del código y la base en cada carga.

Por qué: una lista escrita a mano envejece sin que nadie se entere. Una generada no puede mentir.

Deuda técnica conocida

Columnas can_* que no hacen nada

role_modules tiene can_view, can_create, can_edit, can_delete, can_export — y el control de acceso no las lee. Solo usa permission (read/write).

Riesgo: poner can_edit = 0 da falsa sensación de haber restringido algo. Ya causó confusión.

Arreglo: o se usan de verdad, o se eliminan. Mientras tanto, conviene mantenerlas coherentes con permission.

role y role_id duplicados

Un usuario tiene el rol en dos columnas. La interfaz lee una, los permisos salen de la otra.

Riesgo: cambiar solo role deja al usuario con permisos que no corresponden.

Arreglo: derivar role de role_id en lugar de almacenarlo.

Dos vías para el mismo formulario

turnero_consentimientos y lab_form_envios guardan lo mismo con estructuras distintas y tokens de formato distinto. ver_formulario_enviado.php tiene que manejar ambos, y form_cliente.php existe solo para redirigir entre ellos.

Por qué sigue así: unificarlas obliga a cambiar la plantilla aprobada en Meta y migrar los registros históricos.

Convenciones de nombre mezcladas

Conviven creado_at y created_at, creado_por y enviado_por, español e inglés. Depende de la época de cada tabla.

Vistas muy grandes

ver_formulario_enviado.php supera las 3.000 líneas y mezcla render, lógica de tomas prolongadas y JavaScript. Es el archivo más delicado de tocar del sistema.

Datos históricos incompletos

Algunas columnas se agregaron después y las filas viejas quedaron en NULL, sin forma de recuperarlas:

Columna Desde Antes
turnero_consentimientos.creado_por 3 ago 2026 NULL
Identidad por toma en F-LAB-28 3 ago 2026 No se guardaba
admin_users.cedula 3 ago 2026 Solo enfermeros la tenían

No hay traza de auditoría que permita reconstruirlos.

El dominio se deduce de cada petición

APP_URL sale del HTTP_HOST. Si alguien entra por una IP o un dominio alterno, los enlaces que se generen llevarán esa dirección — y quedan guardados así en el WhatsApp del paciente.

Arreglo: fijar APP_URL explícitamente.

Al hacer cambios

  • Cambio de esquema → deje la migración en migrations/, idempotente.
  • Endpoint nuevo → verifique permisos ahí adentro, no confíes en la vista.
  • Tocar el turnero → es lo que más gente usa a diario; pruebe con un turno real.
  • Tocar formularios firmados → tienen valor legal. Un render roto es un documento inválido.