# Base de datos — `usite_whatsapp_bot` Documentación de las 34 tablas del sistema WhatsApp Bot + Panel Laboratorio Ximena. Motor: **MariaDB / MySQL 8.x** — Charset: `utf8mb4` — Collation: `utf8mb4_unicode_ci` --- ## Índice rápido | # | Tabla | Filas (prod) | Dominio | |---|-------|-------------|---------| | 1 | [admin\_users](#1-admin_users) | 4 | Autenticación | | 2 | [autoresponses](#2-autoresponses) | 6 | Bot WhatsApp | | 3 | [conversations](#3-conversations) | 3 490 | Bot WhatsApp | | 4 | [file\_request\_uploads](#4-file_request_uploads) | 0 | Solicitud archivos | | 5 | [file\_requests](#5-file_requests) | 0 | Solicitud archivos | | 6 | [lab\_actividad\_admin](#6-lab_actividad_admin) | 43 | Auditoría | | 7 | [lab\_asignaciones](#7-lab_asignaciones) | 4 | Laboratorio | | 8 | [lab\_autorizaciones](#8-lab_autorizaciones) | 0 | Laboratorio | | 9 | [lab\_config](#9-lab_config) | 9 | Laboratorio | | 10 | [lab\_domicilios](#10-lab_domicilios) | 9 | Laboratorio | | 11 | [lab\_enfermeras](#11-lab_enfermeras) | 1 | Laboratorio | | 12 | [lab\_form\_envios](#12-lab_form_envios) | 15 | Formularios | | 13 | [lab\_formularios](#13-lab_formularios) | 3 | Formularios | | 14 | [lab\_ordenes\_medicas](#14-lab_ordenes_medicas) | 0 | Laboratorio | | 15 | [lab\_pacientes](#15-lab_pacientes) | 3 | Laboratorio | | 16 | [lab\_servicios\_extra](#16-lab_servicios_extra) | 0 | Laboratorio | | 17 | [media\_files](#17-media_files) | 231 | Multimedia | | 18 | [media\_queue](#18-media_queue) | 7 | Multimedia | | 19 | [menu\_options](#19-menu_options) | 13 | Bot WhatsApp | | 20 | [menus](#20-menus) | 2 | Bot WhatsApp | | 21 | [message\_templates](#21-message_templates) | 2 | Bot WhatsApp | | 22 | [migrations](#22-migrations) | 4 | Sistema | | 23 | [notifications](#23-notifications) | 2 073 | Sistema | | 24 | [operator\_activity](#24-operator_activity) | 227 | Operadores | | 25 | [role\_modules](#25-role_modules) | 12 | Control de acceso | | 26 | [roles](#26-roles) | 2 | Control de acceso | | 27 | [scheduled\_messages](#27-scheduled_messages) | — | Mensajes prog. | | 28 | [scheduled\_messages\_view](#28-scheduled_messages_view-vista) | — | Vista | | 29 | [survey\_responses](#29-survey_responses) | 10 | Bot WhatsApp | | 30 | [system\_config](#30-system_config) | 16 | Configuración | | 31 | [system\_logs](#31-system_logs) | 0 | Sistema | | 32 | [terms\_acceptance](#32-terms_acceptance) | 0 | T&C | | 33 | [terms\_versions](#33-terms_versions) | 2 | T&C | | 34 | [user\_states](#34-user_states) | 108 | Bot WhatsApp | | 35 | [users](#35-users) | 3 090 | Usuarios | | 36 | [webhook\_logs](#36-webhook_logs) | 9 850 | Sistema | --- ## Autenticación ### 1. `admin_users` Administradores del panel web. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `username` | VARCHAR(50) UNIQUE | Login | | `password` | VARCHAR(255) | bcrypt | | `role_id` | INT FK→roles | Rol asignado (NULL = admin clásico) | | `email` | VARCHAR(100) | | | `nombre` | VARCHAR(100) | Nombre completo | | `is_active` | TINYINT(1) | 1 = activo | | `last_login` | DATETIME | | | `created_at` | TIMESTAMP | | **Relaciones:** `role_id` → `roles.id` --- ## Bot WhatsApp ### 2. `autoresponses` Respuestas automáticas del bot ante palabras clave. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `keyword` | VARCHAR(100) | Palabra/frase que activa la respuesta | | `response` | TEXT | Texto de respuesta | | `is_active` | TINYINT(1) | | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 3. `conversations` Hilo de mensajes WhatsApp por número de teléfono. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `phone_number` | VARCHAR(20) | Número del usuario | | `contact_name` | VARCHAR(100) | Nombre de WhatsApp | | `messages` | LONGTEXT (JSON) | Array de mensajes | | `last_message` | TEXT | Extracto del último mensaje | | `last_message_at` | DATETIME | | | `unread_count` | INT | Mensajes no leídos por operador | | `status` | ENUM | `active`, `archived`, `blocked` | | `assigned_to` | INT FK→admin_users | Operador asignado | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 4. `file_request_uploads` Archivos subidos en respuesta a solicitudes. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `request_id` | INT FK→file_requests | | | `file_path` | VARCHAR(500) | Ruta en servidor | | `file_type` | VARCHAR(50) | MIME | | `uploaded_at` | DATETIME | | --- ### 5. `file_requests` Solicitudes de documentos enviadas por WhatsApp. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `phone_number` | VARCHAR(20) | | | `request_type` | VARCHAR(50) | Tipo de documento solicitado | | `status` | ENUM | `pending`, `fulfilled`, `expired` | | `expires_at` | DATETIME | | | `created_at` | TIMESTAMP | | --- ### 19. `menu_options` Opciones de submenú del bot (hijos de `menus`). | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `menu_id` | INT FK→menus | | | `option_number` | INT | Tecla que selecciona el usuario | | `option_text` | VARCHAR(200) | Texto visible | | `action_type` | VARCHAR(50) | `submenu`, `message`, `url`, `form_link` | | `action_value` | TEXT | Valor de la acción | | `is_active` | TINYINT(1) | | | `sort_order` | INT | | --- ### 20. `menus` Menús raíz del bot por número de teléfono de negocio. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `phone_number_id` | VARCHAR(50) | ID de WhatsApp Business | | `menu_text` | TEXT | Texto del menú principal | | `is_active` | TINYINT(1) | | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 21. `message_templates` Plantillas de mensajes aprobadas por Meta. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `name` | VARCHAR(100) | Nombre interno | | `display_name` | VARCHAR(150) | Nombre legible | | `category` | VARCHAR(50) | `MARKETING`, `UTILITY`, `AUTHENTICATION` | | `language` | VARCHAR(10) | `es`, `en`, etc. | | `status` | VARCHAR(30) | `APPROVED`, `PENDING`, `REJECTED` | | `header_type` | VARCHAR(20) | `TEXT`, `IMAGE`, `DOCUMENT`, `NONE` | | `header_text` | VARCHAR(500) | | | `body_text` | TEXT | Cuerpo de la plantilla | | `footer_text` | VARCHAR(300) | | | `buttons` | LONGTEXT (JSON) | Botones quick-reply / CTA | | `variables_count` | INT | Número de `{{n}}` en body | | `meta_template_id` | VARCHAR(50) | ID en Meta Graph API | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 29. `survey_responses` Respuestas a encuestas del bot. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `phone_number` | VARCHAR(20) | | | `survey_id` | INT | Identificador de encuesta | | `question_key` | VARCHAR(100) | | | `answer` | TEXT | | | `created_at` | TIMESTAMP | | --- ### 34. `user_states` Estado de conversación del bot por usuario (máquina de estados). | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `phone_number` | VARCHAR(20) UNIQUE | | | `state` | VARCHAR(100) | Estado actual del flujo del bot | | `context` | LONGTEXT (JSON) | Datos contextuales del estado | | `updated_at` | DATETIME | | --- ## Laboratorio ### 6. `lab_actividad_admin` Log de acciones de administradores en el laboratorio. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `admin_id` | INT FK→admin_users | | | `accion` | VARCHAR(100) | Descripción de la acción | | `entidad` | VARCHAR(50) | Tabla/módulo afectado | | `entidad_id` | INT | ID del registro afectado | | `datos_extra` | TEXT (JSON) | Detalles adicionales | | `ip` | VARCHAR(45) | | | `created_at` | TIMESTAMP | | --- ### 7. `lab_asignaciones` Asignaciones de servicios domiciliarios a enfermeras. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `domicilio_id` | INT FK→lab_domicilios | | | `enfermera_id` | INT FK→lab_enfermeras | | | `estado` | ENUM | `pendiente`, `aceptado`, `rechazado`, `completado` | | `fecha_asignacion` | DATETIME | | | `fecha_respuesta` | DATETIME | | | `notas` | TEXT | | --- ### 8. `lab_autorizaciones` Autorizaciones médicas/seguros para servicios del laboratorio. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `paciente_id` | INT FK→lab_pacientes | | | `tipo` | VARCHAR(50) | Tipo de autorización | | `numero_autorizacion` | VARCHAR(100) | | | `aseguradora` | VARCHAR(100) | | | `fecha_vencimiento` | DATE | | | `estado` | ENUM | `vigente`, `vencida` | | `created_at` | TIMESTAMP | | --- ### 9. `lab_config` Configuración específica del módulo de laboratorio (clave–valor). | Columna | Tipo | Notas | |---------|------|-------| | `clave` | VARCHAR(80) PK | Nombre de la configuración | | `valor` | LONGTEXT | Valor | | `updated_at` | TIMESTAMP | | Ejemplos de claves: `empresa_nombre`, `empresa_nit`, `empresa_direccion`, `empresa_telefono`, `empresa_email`, `empresa_ciudad`, etc. --- ### 10. `lab_domicilios` Solicitudes de servicio domiciliario de laboratorio. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `paciente_id` | INT FK→lab_pacientes | | | `fecha_solicitud` | DATE | | | `hora_solicitud` | TIME | | | `direccion` | VARCHAR(300) | | | `ciudad` | VARCHAR(100) | | | `estado` | ENUM | `pendiente`, `asignado`, `en_camino`, `completado`, `cancelado` | | `observaciones` | TEXT | | | `examen_solicitado` | TEXT | | | `creado_por` | INT FK→admin_users | | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 11. `lab_enfermeras` Enfermeras/profesionales de campo del laboratorio. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `nombre` | VARCHAR(150) | | | `telefono` | VARCHAR(20) | | | `email` | VARCHAR(100) | | | `phone_number_wa` | VARCHAR(20) | Número WhatsApp para notificaciones | | `is_active` | TINYINT(1) | | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 12. `lab_form_envios` Instancias de formularios enviados/completados por pacientes. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `formulario_id` | INT FK→lab_formularios | | | `paciente_id` | INT FK→lab_pacientes | | | `phone_number` | VARCHAR(20) | | | `datos_json` | LONGTEXT (JSON) | Respuestas del formulario | | `firma_base64` | LONGTEXT | Firma digital en Base64 | | `pdf_path` | VARCHAR(500) | Ruta del PDF generado | | `hash_verificacion` | CHAR(64) | SHA-256 del PDF para integridad | | `estado` | ENUM | `borrador`, `enviado`, `procesado` | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 13. `lab_formularios` Definición de formularios médicos configurables. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `nombre` | VARCHAR(150) | | | `descripcion` | TEXT | | | `categoria` | ENUM | `consentimiento`, `historia_clinica`, `autorizacion`, `encuesta`, `otro` | | `esquema` | LONGTEXT (JSON) | Definición de campos del formulario | | `permite_firma` | TINYINT(1) | | | `requiere_firma` | TINYINT(1) | | | `version` | SMALLINT | | | `is_active` | TINYINT(1) | | | `doc_encabezado` | VARCHAR(200) | Título en PDF | | `doc_subtitulo` | VARCHAR(200) | Subtítulo en PDF | | `doc_logo_base64` | LONGTEXT | Logo en Base64 para PDF | | `doc_color` | VARCHAR(20) | Color principal HEX para PDF | | `doc_pie_pagina` | VARCHAR(500) | Pie de página del PDF | | `creado_por` | INT FK→admin_users | | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 14. `lab_ordenes_medicas` Órdenes médicas digitalizadas vinculadas a pacientes. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `paciente_id` | INT FK→lab_pacientes | | | `medico` | VARCHAR(150) | | | `especialidad` | VARCHAR(100) | | | `fecha_orden` | DATE | | | `examenes` | TEXT | Exámenes ordenados | | `archivo_path` | VARCHAR(500) | Imagen/PDF de la orden | | `estado` | ENUM | `pendiente`, `procesada`, `vigente`, `vencida` | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 15. `lab_pacientes` Pacientes registrados en el laboratorio. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `nombre` | VARCHAR(150) | | | `documento` | VARCHAR(30) | Cédula / NIT | | `tipo_documento` | VARCHAR(20) | CC, TI, CE, PA, NIT | | `fecha_nacimiento` | DATE | | | `telefono` | VARCHAR(20) | | | `email` | VARCHAR(100) | | | `direccion` | VARCHAR(300) | | | `eps` | VARCHAR(100) | Aseguradora de salud | | `phone_number_wa` | VARCHAR(20) | Número WhatsApp → `users.phone_number` | | `created_at` / `updated_at` | TIMESTAMP | | --- ### 16. `lab_servicios_extra` Servicios adicionales configurables del laboratorio (transporte, procesamiento especial, etc.). | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `nombre` | VARCHAR(100) | | | `descripcion` | TEXT | | | `precio` | DECIMAL(10,2) | | | `is_active` | TINYINT(1) | | | `created_at` | TIMESTAMP | | --- ## Multimedia ### 17. `media_files` Archivos multimedia subidos o recibidos por WhatsApp. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `media_id` | VARCHAR(100) | ID en la API de WhatsApp | | `file_name` | VARCHAR(255) | | | `file_path` | VARCHAR(500) | Ruta local | | `file_size` | BIGINT | Bytes | | `mime_type` | VARCHAR(100) | | | `phone_number` | VARCHAR(20) | Remitente o destinatario | | `direction` | ENUM | `incoming`, `outgoing` | | `created_at` | TIMESTAMP | | --- ### 18. `media_queue` Cola de transmisión de archivos multimedia grandes. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `media_file_id` | INT FK→media_files | | | `status` | ENUM | `pending`, `processing`, `done`, `failed` | | `attempts` | INT | Reintentos | | `error_message` | TEXT | | | `created_at` / `updated_at` | TIMESTAMP | | --- ## Mensajes Programados ### 27. `scheduled_messages` Mensajes de WhatsApp programados para envío futuro. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `user_id` | INT FK→users | Destinatario | | `template_id` | INT FK→message_templates | Plantilla a usar | | `template_name` | VARCHAR(100) | Nombre snapshot de la plantilla | | `template_language` | VARCHAR(10) | `es`, `en` | | `template_parameters` | LONGTEXT (JSON) | Variables `{{n}}` | | `message_type` | ENUM | `template`, `text` | | `message_content` | TEXT | Mensaje libre (si type=text) | | `scheduled_date` | DATE | Fecha de envío | | `scheduled_time` | TIME | Hora de envío | | `status` | ENUM | `pending`, `sent`, `failed`, `cancelled` | | `sent_at` | DATETIME | | | `error_message` | TEXT | | | `created_by` | INT FK→admin_users | Admin que creó el recordatorio | | `created_at` / `updated_at` | DATETIME | | --- ### 28. `scheduled_messages_view` (VISTA) Enriquece `scheduled_messages` con datos del usuario, plantilla y nombre del admin. Columnas adicionales: `user_name`, `phone_number`, `template_display_name`, `template_body`, `template_status`. --- ## Control de Acceso ### 25. `role_modules` Asociación entre roles y módulos del sistema (permisos). | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `role_id` | INT FK→roles | | | `module_slug` | VARCHAR(100) | Clave del módulo (ej. `lab`, `bot`, `config`) | --- ### 26. `roles` Roles del sistema para control de acceso basado en roles (RBAC). | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `name` | VARCHAR(100) | Nombre legible | | `slug` | VARCHAR(50) UNIQUE | Clave interna (`admin`, `enfermero`) | | `description` | TEXT | | | `color` | VARCHAR(20) | Color HEX para UI | | `is_system` | TINYINT(1) | 1 = no eliminable | | `created_at` / `updated_at` | TIMESTAMP | | Roles de sistema predefinidos: `admin` (id=1), `enfermero` (id=2). --- ## Términos y Condiciones (T&C) ### 32. `terms_acceptance` Registro de aceptaciones/rechazos de T&C por usuario. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `phone_number` | VARCHAR(20) | | | `version_id` | INT FK→terms_versions | Versión enviada | | `estado` | ENUM | `pendiente`, `aceptado`, `rechazado` | | `fecha_envio` | DATETIME | Cuándo se enviaron los T&C | | `fecha_respuesta` | DATETIME | Cuándo respondió el usuario | | `ip_origem` | VARCHAR(45) | IP de origen (si aplica) | --- ### 33. `terms_versions` Versiones publicadas de los Términos y Condiciones. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `version` | VARCHAR(20) | Ej. `v1.0` | | `titulo` | VARCHAR(200) | | | `mensaje_bot` | TEXT | Texto enviado por WhatsApp | | `mensaje_rechazo` | TEXT | Texto si el usuario rechaza | | `pdf_url` | VARCHAR(500) | URL pública del PDF | | `pdf_path` | VARCHAR(500) | Ruta local del archivo | | `es_activa` | TINYINT(1) | Solo una activa a la vez | | `forzar_reenvio` | TINYINT(1) | 1 = todos deben re-aceptar | | `created_at` | TIMESTAMP | | | `created_by` | INT FK→admin_users | | --- ## Configuración y Sistema ### 22. `migrations` Registro de migraciones de BD aplicadas. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `name` | VARCHAR(255) | Nombre del archivo de migración | | `applied_at` | TIMESTAMP | | Migraciones aplicadas: `01_initial.sql`, `02_…`, `03_…`, `05_terms_acceptance.sql`, `06_master_sync.sql`. --- ### 23. `notifications` Notificaciones del sistema enviadas a admins. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `admin_id` | INT FK→admin_users | NULL = broadcast | | `type` | VARCHAR(50) | `new_message`, `assignment`, `system` | | `title` | VARCHAR(200) | | | `body` | TEXT | | | `is_read` | TINYINT(1) | | | `created_at` | TIMESTAMP | | --- ### 24. `operator_activity` Actividad reciente de operadores (mensajes enviados, conversaciones gestionadas). | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `admin_id` | INT FK→admin_users | | | `action` | VARCHAR(100) | `send_message`, `view_conversation`, etc. | | `phone_number` | VARCHAR(20) | Número implicado | | `details` | TEXT (JSON) | | | `created_at` | TIMESTAMP | | --- ### 30. `system_config` Configuración global del sistema (clave–valor). | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `config_key` | VARCHAR(100) UNIQUE | | | `config_value` | TEXT | | | `description` | VARCHAR(255) | | | `updated_at` | TIMESTAMP | | Claves principales: `whatsapp_token`, `whatsapp_phone_number_id`, `whatsapp_verify_token`, `bot_enabled`, `welcome_message`, `terms_message`, `terms_rejection_message`, `terms_pdf_url`, `terms_version`, `terms_force_resend`. --- ### 31. `system_logs` Logs de errores y eventos del sistema. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `level` | ENUM | `info`, `warning`, `error`, `critical` | | `message` | TEXT | | | `context` | LONGTEXT (JSON) | Stack trace, datos extra | | `created_at` | TIMESTAMP | | --- ### 36. `webhook_logs` Log de todos los webhooks entrantes de WhatsApp. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `payload` | LONGTEXT (JSON) | Payload completo recibido | | `event_type` | VARCHAR(50) | `message`, `status`, `read` | | `phone_number` | VARCHAR(20) | | | `processed` | TINYINT(1) | | | `error` | TEXT | Error si falló el procesamiento | | `created_at` | TIMESTAMP | | --- ## Usuarios ### 35. `users` Usuarios de WhatsApp que han interactuado con el bot. | Columna | Tipo | Notas | |---------|------|-------| | `id` | INT PK | | | `phone_number` | VARCHAR(20) UNIQUE | Número de WhatsApp | | `name` | VARCHAR(100) | Nombre de contacto en WhatsApp | | `is_blocked` | TINYINT(1) | 1 = bloqueado | | `bot_enabled` | TINYINT(1) | 1 = bot activo para este usuario | | `last_interaction` | DATETIME | | | `terms_pending` | TINYINT(1) | 1 = aún no aceptó T&C | | `terms_accepted_at` | DATETIME | Fecha de aceptación | | `terms_version_id` | INT FK→terms_versions | Versión aceptada | | `created_at` / `updated_at` | TIMESTAMP | | --- ## Diagrama ER simplificado ``` users ──────────────────────────────────┐ │ 1:N terms_acceptance │ │ 1:N scheduled_messages │ │ 1:N conversations │ user_states (1:1 phone_number) │ │ admin_users ─────── roles ──── role_modules │ 1:N lab_actividad_admin │ 1:N lab_domicilios ──── lab_asignaciones ── lab_enfermeras │ 1:N lab_form_envios ── lab_formularios │ 1:N lab_ordenes_medicas ── lab_pacientes ── lab_autorizaciones │ 1:N terms_versions (created_by) │ menus ─── menu_options message_templates ─── scheduled_messages media_files ─── media_queue ``` --- *Última actualización: generado automáticamente desde comparación local/prod — ver `database/06_master_sync.sql`*