Files
whatsapp/migrations/005_registro_exams.sql

125 lines
7.2 KiB
SQL

-- =============================================================
-- Migración 005 — Registro de Exámenes (Oleada 2)
-- Crear: exec_ordenes, exam_items, exam_muestras, exam_resultados
-- Extender: exam_tipos (precio, ayuno, instrucciones)
-- Activar: módulo registro_exams en system_modules
-- =============================================================
-- -----------------------------------------------------------
-- 1. Extender exam_tipos con campos clínicos
-- -----------------------------------------------------------
ALTER TABLE exam_tipos
ADD COLUMN IF NOT EXISTS precio_base DECIMAL(10,2) DEFAULT NULL COMMENT 'Precio de venta al público',
ADD COLUMN IF NOT EXISTS requiere_ayuno TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 = requiere ayuno',
ADD COLUMN IF NOT EXISTS horas_ayuno TINYINT(3) DEFAULT NULL COMMENT 'Horas mínimas de ayuno',
ADD COLUMN IF NOT EXISTS instrucciones TEXT DEFAULT NULL COMMENT 'Instrucciones de preparación para el paciente';
-- -----------------------------------------------------------
-- 2. Órdenes de examen (una orden por visita)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS exam_ordenes (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
paciente_id INT NOT NULL COMMENT 'FK lab_pacientes.id',
solicitud_id INT UNSIGNED DEFAULT NULL COMMENT 'FK turnero_solicitudes.id (opcional)',
orden_medica_id INT DEFAULT NULL COMMENT 'FK lab_ordenes_medicas.id (opcional)',
codigo VARCHAR(20) NOT NULL COMMENT 'Código legible EX-YYYYMMDD-NNNN',
medico_nombre VARCHAR(150) DEFAULT NULL,
medico_registro VARCHAR(50) DEFAULT NULL,
diagnostico TEXT DEFAULT NULL,
requiere_ayuno TINYINT(1) NOT NULL DEFAULT 0,
horas_ayuno TINYINT(3) DEFAULT NULL,
prioridad ENUM('normal','urgente','stat') NOT NULL DEFAULT 'normal',
estado ENUM('pendiente','en_proceso','completa','entregada','cancelada') NOT NULL DEFAULT 'pendiente',
notas TEXT DEFAULT NULL,
creado_por INT DEFAULT NULL COMMENT 'FK admin_users.id',
creado_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_codigo (codigo),
KEY idx_paciente (paciente_id),
KEY idx_solicitud (solicitud_id),
KEY idx_estado (estado),
KEY idx_creado_at (creado_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -----------------------------------------------------------
-- 3. Ítems individuales de la orden (por tipo de examen)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS exam_items (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
orden_id INT UNSIGNED NOT NULL COMMENT 'FK exam_ordenes.id',
exam_tipo_id INT UNSIGNED NOT NULL COMMENT 'FK exam_tipos.id',
estado ENUM('pendiente','muestra_tomada','en_proceso','resultado_listo','entregado') NOT NULL DEFAULT 'pendiente',
notas_tecnico TEXT DEFAULT NULL,
creado_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_orden (orden_id),
KEY idx_tipo (exam_tipo_id),
KEY idx_estado (estado),
CONSTRAINT fk_ei_orden FOREIGN KEY (orden_id) REFERENCES exam_ordenes (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -----------------------------------------------------------
-- 4. Trazabilidad de muestras
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS exam_muestras (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
orden_id INT UNSIGNED NOT NULL COMMENT 'FK exam_ordenes.id',
tipo_muestra ENUM(
'sangre_venosa','sangre_capilar',
'orina_24h','orina_espontanea',
'heces','esputo','hisopado','otro'
) NOT NULL DEFAULT 'sangre_venosa',
codigo_barras VARCHAR(50) DEFAULT NULL,
tomada_por INT DEFAULT NULL COMMENT 'FK admin_users.id',
tomada_at DATETIME DEFAULT NULL,
observaciones TEXT DEFAULT NULL,
estado ENUM('pendiente','tomada','procesando','procesada','rechazada') NOT NULL DEFAULT 'pendiente',
PRIMARY KEY (id),
KEY idx_orden (orden_id),
KEY idx_barras (codigo_barras),
CONSTRAINT fk_em_orden FOREIGN KEY (orden_id) REFERENCES exam_ordenes (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -----------------------------------------------------------
-- 5. Resultados por ítem (valor por campo analítico)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS exam_resultados (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
item_id INT UNSIGNED NOT NULL COMMENT 'FK exam_items.id',
campo_nombre VARCHAR(100) NOT NULL COMMENT 'Ej: Hemoglobina, Glucosa',
valor_texto TEXT DEFAULT NULL COMMENT 'Resultado en texto libre',
valor_numerico DECIMAL(12,4) DEFAULT NULL COMMENT 'Resultado numérico (si aplica)',
unidad VARCHAR(50) DEFAULT NULL COMMENT 'g/dL, mg/dL, etc.',
referencia_min DECIMAL(12,4) DEFAULT NULL,
referencia_max DECIMAL(12,4) DEFAULT NULL,
referencia_texto VARCHAR(400) DEFAULT NULL COMMENT 'Rango en texto para imprimir',
es_anormal TINYINT(1) NOT NULL DEFAULT 0,
ingresado_por INT DEFAULT NULL COMMENT 'FK admin_users.id',
ingresado_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_item (item_id),
CONSTRAINT fk_er_item FOREIGN KEY (item_id) REFERENCES exam_items (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- -----------------------------------------------------------
-- 6. Activar el módulo registro_exams
-- -----------------------------------------------------------
UPDATE system_modules
SET is_active = 1
WHERE slug = 'registro_exams';
-- -----------------------------------------------------------
-- 7. Permisos de roles para el módulo (bacteriólogo + recepcionista)
-- Tabla real: role_modules (role_id, module_slug, can_view, can_create, can_edit, can_delete, can_export)
-- -----------------------------------------------------------
INSERT IGNORE INTO role_modules (role_id, module_slug, can_view, can_create, can_edit, can_delete, can_export)
SELECT r.id, 'registro_exams', 1, 1, 1, 0, 1
FROM roles r
WHERE r.slug = 'bacteriologo';
INSERT IGNORE INTO role_modules (role_id, module_slug, can_view, can_create, can_edit, can_delete, can_export)
SELECT r.id, 'registro_exams', 1, 1, 0, 0, 0
FROM roles r
WHERE r.slug = 'recepcionista';