Files
whatsapp/modules/soporte/docs/arquitectura/40-modelo-de-datos.md
T
Lizandro GuarnizoandClaude Opus 5 018fb13332 Módulo Soporte: visor de documentación con renderizado Markdown y buscador
Nuevo módulo `soporte` con la documentación del proyecto en cuatro secciones:
manual de usuario (visible para todos), y documentación técnica, arquitectura
y operación (solo administradores).

- Markdown.php: renderizador propio del subconjunto que usa la documentación
  (encabezados, listas anidadas, tablas, código, citas). Escapa todo el texto
  antes de aplicar formato, así que los .md no pueden inyectar HTML. Se
  prefirió un archivo auditable a incorporar una dependencia externa.
- DocIndex.php: descubre los .md, arma el árbol, resuelve acceso por sección
  y construye el índice del buscador.
- Generadores.php: expande marcadores {{modulos}}, {{endpoints}}, {{tablas}},
  {{roles}} y {{servicios}} leyendo el código y la base en cada carga, para
  que los inventarios no puedan quedar desactualizados.

Se registra en SYSTEM_MODULES y se concede a los 12 roles con permission=read.

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

86 lines
3.6 KiB
Markdown

# Modelo de datos
Las tablas están agrupadas por prefijo, y el prefijo dice a qué dominio pertenecen.
| Prefijo | Dominio |
|---|---|
| `lab_` | Laboratorio: pacientes, domicilios, órdenes, formularios, configuración |
| `turnero_` | Turnos presenciales: sesiones, turnos, solicitudes, muestras, consentimientos |
| `exam_` | Catálogo de exámenes y sus consentimientos asociados |
| `terms_` | Términos y condiciones del bot y su historial de aceptaciones |
| `admin_`, `roles`, `role_modules` | Usuarios y permisos |
| resto | Conversaciones de WhatsApp, plantillas, logs, configuración del sistema |
## Los cuatro núcleos
### Turno presencial
Es la cadena más larga del sistema. Un paciente entra al laboratorio y genera esto:
```
turnero_sesiones una fila por día de operación
└── turnero_turnos el turno del paciente (código, estado, tiempos)
├── turnero_solicitudes qué se le va a hacer y cuánto se cobró
│ ├── turnero_examen_items exámenes pedidos
│ └── turnero_muestras muestras a recibir
├── turnero_consentimientos formularios a firmar
└── turnero_comentarios notas del personal
```
`turnero_turnos.estado` gobierna el flujo:
```
espera → en_recepcion → en_espera_lugar → en_servicio → finalizado
ausente / cancelado
```
Solo los turnos **finalizados** cuentan como facturación real; los que están en estados intermedios se reportan aparte como "en proceso". Ausentes y cancelados no cuentan.
### Domicilio
```
lab_domicilios
├── lab_asignaciones qué enfermero lo atiende
├── lab_domicilio_notas seguimiento
└── lab_domicilio_pagos cobros
```
### Formulario firmado
Un mismo formulario (`lab_formularios`) se firma por dos vías distintas, y cada una guarda en su propia tabla:
| Vía | Tabla | Token |
|---|---|---|
| Turnero | `turnero_consentimientos` | UUID (`?token=`) |
| Domicilios y envíos sueltos | `lab_form_envios` | 64 caracteres hex (`?t=`) |
Las dos las muestra `ver_formulario_enviado.php`, que distingue por el **formato del token**. Es la razón de que existan dos parámetros distintos para lo que parece lo mismo.
La definición del formulario vive en `lab_formularios.esquema`, un JSON con la lista de campos. Las respuestas quedan en `datos_respuestas` (turnero) o `datos_cliente` (envíos), también JSON.
### Conversación de WhatsApp
```
users / conversations el contacto y su hilo
├── messages cada mensaje
├── terms_acceptance aceptación de términos
└── message_templates plantillas aprobadas por Meta (caché local)
```
## Convenciones
- **Timestamps**: `creado_at` / `created_at` según la época en que se creó la tabla. No hay una sola convención.
- **Autor**: `creado_por` guarda `admin_users.id`. Varias tablas lo agregaron después, así que las filas viejas lo tienen en `NULL`.
- **Borrado**: casi todo es borrado físico. No hay *soft delete* generalizado.
- **JSON**: se usa bastante (`esquema`, `datos_respuestas`, `pagos_detalle`, `items_precio`). Guardado como `longtext`, no como tipo `JSON` nativo.
## Cambios de esquema
Van en `migrations/`, con nombre `AAAAMMDD_descripcion.sql`. La convención del repositorio es que sean **idempotentes**`IF NOT EXISTS` y guardas en los `UPDATE`/`INSERT` — para poder correrlas más de una vez sin daño.
> Un cambio aplicado directo en producción sin dejar la migración correspondiente hace que un entorno nuevo no lo tenga. Si tocás el esquema, dejá el archivo.
## Inventario completo
{{tablas}}