up
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
-- ============================================================
|
||||
-- Migración 003 – Módulo Turnero (Oleada 1)
|
||||
-- Sistema de Turnero Inteligente con consentimientos informados
|
||||
-- FASE 3.1 del plan ERP multi-módulo.
|
||||
-- Segura para re-ejecutar (IF NOT EXISTS / INSERT IGNORE).
|
||||
-- ============================================================
|
||||
|
||||
-- ── 1. Catálogo maestro de tipos de examen ──────────────────
|
||||
-- Compartido con Oleada 2 (registro_exams).
|
||||
-- En Migración 005 se agregan precio_base, requiere_ayunas, instrucciones.
|
||||
CREATE TABLE IF NOT EXISTS exam_tipos (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
codigo VARCHAR(20) NOT NULL COMMENT 'Ej: HEM, GLU, URIN',
|
||||
nombre VARCHAR(150) NOT NULL COMMENT 'Ej: Hemograma completo',
|
||||
categoria VARCHAR(80) DEFAULT NULL COMMENT 'Ej: Hematología, Química',
|
||||
activo TINYINT(1) NOT NULL DEFAULT 1,
|
||||
creado_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_codigo (codigo),
|
||||
INDEX idx_activo (activo),
|
||||
INDEX idx_categoria (categoria)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='Catálogo maestro de tipos de examen del laboratorio';
|
||||
|
||||
-- ── 2. Relación M:N examen ↔ consentimiento (formulario) ────
|
||||
-- Si un examen no tiene registro aquí, no se exige consentimiento.
|
||||
-- Varios exámenes del mismo turno que apunten al mismo formulario_id
|
||||
-- generan UN SOLO consentimiento (deduplicado en la lógica PHP).
|
||||
CREATE TABLE IF NOT EXISTS exam_tipo_consentimientos (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
exam_tipo_id INT UNSIGNED NOT NULL,
|
||||
formulario_id INT NOT NULL COMMENT 'FK lab_formularios.id (tipo=consentimiento)',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_examen_form (exam_tipo_id, formulario_id),
|
||||
INDEX idx_formulario (formulario_id),
|
||||
CONSTRAINT fk_etc_exam FOREIGN KEY (exam_tipo_id) REFERENCES exam_tipos (id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='M:N entre tipos de examen y formularios de consentimiento';
|
||||
|
||||
-- ── 3. Lugares / estaciones de servicio configurables ───────
|
||||
-- Recepción NO es un lugar; es el paso implícito del flujo.
|
||||
-- Cada lugar tiene su propia cola y su propia pantalla TV.
|
||||
CREATE TABLE IF NOT EXISTS turnero_lugares (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
nombre VARCHAR(100) NOT NULL COMMENT 'Ej: Toma de Muestras 1, Rayos X',
|
||||
descripcion TEXT DEFAULT NULL,
|
||||
activo TINYINT(1) NOT NULL DEFAULT 1,
|
||||
sort_order INT NOT NULL DEFAULT 99 COMMENT 'Orden en pantalla TV general',
|
||||
creado_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
INDEX idx_activo (activo),
|
||||
INDEX idx_sort (sort_order)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='Estaciones de servicio configurables del turnero';
|
||||
|
||||
-- Lugares de ejemplo (ajustar según el laboratorio real)
|
||||
INSERT IGNORE INTO turnero_lugares (id, nombre, descripcion, activo, sort_order) VALUES
|
||||
(1, 'Toma de Muestras 1', 'Primera estación de toma de muestras', 1, 1),
|
||||
(2, 'Toma de Muestras 2', 'Segunda estación de toma de muestras', 1, 2),
|
||||
(3, 'Rayos X', 'Área de radiología', 1, 3);
|
||||
|
||||
-- ── 4. Catálogo de prioridades (códigos A-F) ─────────────────
|
||||
-- Editable desde el panel admin. orden_peso menor = mayor prioridad.
|
||||
CREATE TABLE IF NOT EXISTS turnero_prioridades (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
codigo CHAR(1) NOT NULL COMMENT 'A, B, C, D, E, F',
|
||||
nombre VARCHAR(100) NOT NULL,
|
||||
orden_peso INT NOT NULL COMMENT 'Menor número = mayor prioridad',
|
||||
color VARCHAR(7) NOT NULL DEFAULT '#6b7280' COMMENT 'Hex color para UI',
|
||||
activo TINYINT(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_codigo (codigo),
|
||||
INDEX idx_orden (orden_peso)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='Catálogo configurable de prioridades de atención';
|
||||
|
||||
-- Prioridades por defecto A-F
|
||||
INSERT IGNORE INTO turnero_prioridades (codigo, nombre, orden_peso, color, activo) VALUES
|
||||
('A', 'Niños', 1, '#ef4444', 1),
|
||||
('B', 'Embarazadas', 2, '#f97316', 1),
|
||||
('C', 'Adulto mayor', 3, '#eab308', 1),
|
||||
('D', 'Discapacidad', 4, '#8b5cf6', 1),
|
||||
('E', 'Paciente general', 5, '#3b82f6', 1),
|
||||
('F', 'Muestra pendiente', 6, '#6b7280', 1);
|
||||
|
||||
-- ── 5. Sesiones diarias de atención ─────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS turnero_sesiones (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
fecha DATE NOT NULL,
|
||||
abierto_por INT DEFAULT NULL COMMENT 'FK admin_users.id',
|
||||
cerrado_por INT DEFAULT NULL COMMENT 'FK admin_users.id',
|
||||
inicio_at DATETIME DEFAULT NULL,
|
||||
fin_at DATETIME DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_fecha (fecha),
|
||||
INDEX idx_fecha (fecha)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='Sesión de atención del día (una por fecha)';
|
||||
|
||||
-- ── 6. Turnos ────────────────────────────────────────────────
|
||||
-- Motor principal del módulo. Un turno = un paciente en una visita.
|
||||
CREATE TABLE IF NOT EXISTS turnero_turnos (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
sesion_id INT UNSIGNED NOT NULL,
|
||||
numero INT NOT NULL COMMENT 'Correlativo dentro de la sesión',
|
||||
codigo VARCHAR(10) NOT NULL COMMENT 'Ej: A001, E042',
|
||||
prioridad_id INT UNSIGNED NOT NULL,
|
||||
paciente_nombre VARCHAR(150) DEFAULT NULL COMMENT 'Capturado en kiosko (opcional)',
|
||||
paciente_cel VARCHAR(20) DEFAULT NULL,
|
||||
estado ENUM(
|
||||
'espera',
|
||||
'en_recepcion',
|
||||
'en_espera_lugar',
|
||||
'en_servicio',
|
||||
'finalizado',
|
||||
'ausente',
|
||||
'cancelado'
|
||||
) NOT NULL DEFAULT 'espera',
|
||||
lugar_destino_id INT UNSIGNED DEFAULT NULL COMMENT 'Asignado por recepción',
|
||||
-- Timestamps por etapa
|
||||
creado_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
llamado_recepcion_at DATETIME DEFAULT NULL,
|
||||
inicio_recepcion_at DATETIME DEFAULT NULL,
|
||||
fin_recepcion_at DATETIME DEFAULT NULL,
|
||||
llamado_lugar_at DATETIME DEFAULT NULL,
|
||||
inicio_lugar_at DATETIME DEFAULT NULL,
|
||||
fin_lugar_at DATETIME DEFAULT NULL,
|
||||
-- Responsable de atención
|
||||
atendido_recepcion_por INT DEFAULT NULL COMMENT 'FK admin_users.id',
|
||||
atendido_lugar_por INT DEFAULT NULL COMMENT 'FK admin_users.id',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_sesion_numero (sesion_id, numero),
|
||||
INDEX idx_sesion_estado (sesion_id, estado),
|
||||
INDEX idx_lugar_estado (lugar_destino_id, estado),
|
||||
INDEX idx_prioridad (prioridad_id),
|
||||
INDEX idx_creado (creado_at),
|
||||
CONSTRAINT fk_tt_sesion FOREIGN KEY (sesion_id) REFERENCES turnero_sesiones (id) ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_tt_prioridad FOREIGN KEY (prioridad_id) REFERENCES turnero_prioridades (id) ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_tt_lugar FOREIGN KEY (lugar_destino_id) REFERENCES turnero_lugares (id) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='Turnos del sistema de atención';
|
||||
|
||||
-- ── 7. Solicitud interna (crea recepción) ────────────────────
|
||||
-- Registra paciente, exámenes, pago y lugar destino.
|
||||
-- Una solicitud por turno (UNIQUE turno_id).
|
||||
CREATE TABLE IF NOT EXISTS turnero_solicitudes (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
turno_id INT UNSIGNED NOT NULL,
|
||||
paciente_id INT NOT NULL COMMENT 'FK lab_pacientes.id',
|
||||
lugar_id INT UNSIGNED NOT NULL COMMENT 'FK turnero_lugares.id',
|
||||
total_cobrado DECIMAL(10,2) DEFAULT NULL,
|
||||
metodo_pago ENUM(
|
||||
'efectivo',
|
||||
'transferencia',
|
||||
'tarjeta',
|
||||
'eps',
|
||||
'cortesia'
|
||||
) DEFAULT NULL,
|
||||
observaciones TEXT DEFAULT NULL,
|
||||
creado_por INT NOT NULL COMMENT 'FK admin_users.id',
|
||||
creado_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_turno (turno_id),
|
||||
INDEX idx_paciente (paciente_id),
|
||||
INDEX idx_lugar (lugar_id),
|
||||
INDEX idx_creado (creado_at),
|
||||
CONSTRAINT fk_ts_turno FOREIGN KEY (turno_id) REFERENCES turnero_turnos (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_ts_lugar FOREIGN KEY (lugar_id) REFERENCES turnero_lugares (id) ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='Solicitud interna de agendamiento creada en recepción';
|
||||
|
||||
-- ── 8. Exámenes de la solicitud ──────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS turnero_examen_items (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
solicitud_id INT UNSIGNED NOT NULL,
|
||||
exam_tipo_id INT UNSIGNED NOT NULL,
|
||||
creado_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
INDEX idx_solicitud (solicitud_id),
|
||||
INDEX idx_exam_tipo (exam_tipo_id),
|
||||
CONSTRAINT fk_tei_solicitud FOREIGN KEY (solicitud_id) REFERENCES turnero_solicitudes (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_tei_exam FOREIGN KEY (exam_tipo_id) REFERENCES exam_tipos (id) ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='Exámenes individuales de cada solicitud de turno';
|
||||
|
||||
-- ── 9. Consentimientos por turno (deduplicados) ──────────────
|
||||
-- Un registro por formulario distinto requerido en el turno.
|
||||
-- token = enlace único de firma (UUID).
|
||||
CREATE TABLE IF NOT EXISTS turnero_consentimientos (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
turno_id INT UNSIGNED NOT NULL,
|
||||
formulario_id INT NOT NULL COMMENT 'FK lab_formularios.id',
|
||||
token VARCHAR(64) NOT NULL COMMENT 'UUID único para enlace de firma',
|
||||
estado ENUM(
|
||||
'pendiente',
|
||||
'enviado',
|
||||
'visto',
|
||||
'firmado',
|
||||
'rechazado'
|
||||
) NOT NULL DEFAULT 'pendiente',
|
||||
enviado_at DATETIME DEFAULT NULL,
|
||||
firmado_at DATETIME DEFAULT NULL,
|
||||
ip_firma VARCHAR(45) DEFAULT NULL COMMENT 'IPv4 o IPv6 del firmante',
|
||||
ua_firma VARCHAR(500) DEFAULT NULL COMMENT 'User-Agent del dispositivo',
|
||||
version_formulario INT DEFAULT NULL COMMENT 'Snapshot de versión al firmar',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_token (token),
|
||||
UNIQUE KEY uq_turno_form (turno_id, formulario_id),
|
||||
INDEX idx_turno (turno_id),
|
||||
INDEX idx_estado (estado),
|
||||
CONSTRAINT fk_tc_turno FOREIGN KEY (turno_id) REFERENCES turnero_turnos (id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
COMMENT='Consentimientos informados vinculados a un turno (uno por formulario distinto)';
|
||||
|
||||
-- ── 10. Columna tipo en lab_formularios ──────────────────────
|
||||
-- Permite marcar un formulario como consentimiento informado.
|
||||
ALTER TABLE lab_formularios
|
||||
ADD COLUMN IF NOT EXISTS tipo
|
||||
ENUM('formulario', 'consentimiento') NOT NULL DEFAULT 'formulario'
|
||||
COMMENT 'Tipo de formulario: genérico o consentimiento informado';
|
||||
|
||||
-- Índice para filtrar rápido en las consultas del turnero
|
||||
ALTER TABLE lab_formularios
|
||||
ADD INDEX IF NOT EXISTS idx_tipo (tipo);
|
||||
|
||||
-- ── 11. Asignar módulo turnero a roles ───────────────────────
|
||||
-- Activar en system_modules si estaba inactivo
|
||||
UPDATE system_modules
|
||||
SET is_active = 1
|
||||
WHERE slug = 'turnero';
|
||||
|
||||
-- Permisos del recepcionista sobre el módulo turnero
|
||||
INSERT IGNORE INTO role_modules (role_id, module_slug, can_view, can_create, can_edit, can_delete, can_export)
|
||||
SELECT r.id, 'turnero', 1, 1, 1, 0, 0
|
||||
FROM roles r WHERE r.slug = 'recepcionista';
|
||||
|
||||
-- Permisos del bacteriólogo sobre el módulo turnero (solo lectura + edición de servicio)
|
||||
INSERT IGNORE INTO role_modules (role_id, module_slug, can_view, can_create, can_edit, can_delete, can_export)
|
||||
SELECT r.id, 'turnero', 1, 0, 1, 0, 0
|
||||
FROM roles r WHERE r.slug = 'bacteriologo';
|
||||
|
||||
-- ── 12. Datos de ejemplo de tipos de examen ──────────────────
|
||||
-- Solo si la tabla está vacía (evita duplicar en re-ejecución)
|
||||
INSERT IGNORE INTO exam_tipos (codigo, nombre, categoria) VALUES
|
||||
('HEM', 'Hemograma completo', 'Hematología'),
|
||||
('GLU', 'Glucosa en ayunas', 'Química'),
|
||||
('URIN', 'Uroanálisis completo', 'Urología'),
|
||||
('UROCUL','Urocultivo', 'Microbiología'),
|
||||
('COLEST','Perfil lipídico (colesterol)', 'Química'),
|
||||
('TSH', 'TSH (Función tiroidea)', 'Endocrinología'),
|
||||
('HIV', 'Prueba VIH', 'Serología'),
|
||||
('HEPB', 'Hepatitis B (HBsAg)', 'Serología'),
|
||||
('RXP', 'Rayos X de pecho', 'Radiología'),
|
||||
('ECG', 'Electrocardiograma', 'Cardiología');
|
||||
Reference in New Issue
Block a user