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');
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Descriptor del módulo Turnero — Oleada 1
|
||||
* Sistema de Turnero Inteligente con gestión de consentimientos informados.
|
||||
*/
|
||||
return [
|
||||
'slug' => 'turnero',
|
||||
'name' => 'Turnero',
|
||||
'icon' => 'fas fa-ticket-alt',
|
||||
'category' => 'turnero',
|
||||
'route' => '/erp.php?m=turnero&v=dashboard',
|
||||
'is_active' => true,
|
||||
'sort_order' => 40,
|
||||
'oleada' => 1,
|
||||
'description' => 'Sistema de turnos presenciales en recepción con prioridades, consentimientos y pantallas TV',
|
||||
'links' => [
|
||||
['name' => 'Dashboard', 'icon' => 'fas fa-tachometer-alt', 'route' => '/erp.php?m=turnero&v=dashboard'],
|
||||
['name' => 'Recepción', 'icon' => 'fas fa-concierge-bell', 'route' => '/erp.php?m=turnero&v=recepcion'],
|
||||
['name' => 'Configuración', 'icon' => 'fas fa-sliders-h', 'route' => '/erp.php?m=turnero&v=configuracion'],
|
||||
['name' => 'Kiosko', 'icon' => 'fas fa-desktop', 'route' => '/erp.php?m=turnero&v=kiosko'],
|
||||
['name' => 'Pantalla TV', 'icon' => 'fas fa-tv', 'route' => '/erp.php?m=turnero&v=display'],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
* Runner — Migración 003: Módulo Turnero (Oleada 1)
|
||||
*
|
||||
* Uso desde terminal:
|
||||
* php run_003_turnero.php
|
||||
*
|
||||
* O desde el navegador (solo en desarrollo, no exponer en producción):
|
||||
* https://tu-dominio/run_003_turnero.php
|
||||
*/
|
||||
|
||||
// Ejecutar solo desde CLI o con token de protección básica en web
|
||||
if (php_sapi_name() !== 'cli') {
|
||||
// En web: exigir token para evitar ejecuciones accidentales
|
||||
$token = $_GET['token'] ?? '';
|
||||
if (empty($token) || $token !== (defined('MIGRATION_TOKEN') ? MIGRATION_TOKEN : '')) {
|
||||
http_response_code(403);
|
||||
die("Acceso denegado. Usa CLI: php run_003_turnero.php\n");
|
||||
}
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/config/config.php';
|
||||
|
||||
$sqlFile = __DIR__ . '/migrations/003_turnero.sql';
|
||||
|
||||
if (!file_exists($sqlFile)) {
|
||||
echo "❌ Archivo no encontrado: $sqlFile\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
$db = Database::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$sql = file_get_contents($sqlFile);
|
||||
$statements = [];
|
||||
|
||||
// Separar sentencias por ; respetando comentarios de línea y bloques
|
||||
$lines = explode("\n", $sql);
|
||||
$current = '';
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$trimmed = trim($line);
|
||||
|
||||
// Saltar líneas de comentario
|
||||
if (str_starts_with($trimmed, '--') || str_starts_with($trimmed, '#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$current .= ' ' . $trimmed;
|
||||
|
||||
if (str_ends_with($trimmed, ';')) {
|
||||
$stmt = trim($current);
|
||||
if (!empty($stmt) && $stmt !== ';') {
|
||||
$statements[] = $stmt;
|
||||
}
|
||||
$current = '';
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n🚀 Ejecutando Migración 003 — Turnero\n";
|
||||
echo str_repeat('─', 60) . "\n\n";
|
||||
|
||||
$ok = 0;
|
||||
$err = 0;
|
||||
|
||||
foreach ($statements as $stmt) {
|
||||
$preview = substr(preg_replace('/\s+/', ' ', $stmt), 0, 90);
|
||||
|
||||
try {
|
||||
$pdo->exec($stmt);
|
||||
echo " ✓ " . $preview . "\n";
|
||||
$ok++;
|
||||
} catch (PDOException $e) {
|
||||
$msg = $e->getMessage();
|
||||
|
||||
// Errores ignorables: duplicado, ya existe, columna ya existe
|
||||
$ignorable = (
|
||||
str_contains($msg, 'Duplicate entry') ||
|
||||
str_contains($msg, 'already exists') ||
|
||||
str_contains($msg, "Duplicate key name")||
|
||||
str_contains($msg, 'errno: 1050') || // table exists
|
||||
str_contains($msg, 'errno: 1060') || // column exists
|
||||
str_contains($msg, 'errno: 1061') // key exists
|
||||
);
|
||||
|
||||
if ($ignorable) {
|
||||
echo " ℹ️ (ya existía) " . $preview . "\n";
|
||||
$ok++;
|
||||
} else {
|
||||
echo " ✗ ERROR: " . $msg . "\n";
|
||||
echo " SQL: " . $preview . "\n\n";
|
||||
$err++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n" . str_repeat('─', 60) . "\n";
|
||||
echo "✅ Completado: $ok OK";
|
||||
if ($err) {
|
||||
echo " | ⚠️ $err errores";
|
||||
}
|
||||
echo "\n\n";
|
||||
|
||||
// ── Verificación post-migración ──────────────────────────
|
||||
echo "📋 Verificación de tablas creadas:\n";
|
||||
|
||||
$tablas = [
|
||||
'exam_tipos', 'exam_tipo_consentimientos',
|
||||
'turnero_lugares', 'turnero_prioridades',
|
||||
'turnero_sesiones', 'turnero_turnos',
|
||||
'turnero_solicitudes', 'turnero_examen_items',
|
||||
'turnero_consentimientos',
|
||||
];
|
||||
|
||||
foreach ($tablas as $tabla) {
|
||||
try {
|
||||
$count = $pdo->query("SELECT COUNT(*) FROM `$tabla`")->fetchColumn();
|
||||
echo " ✓ $tabla ($count filas)\n";
|
||||
} catch (PDOException $e) {
|
||||
echo " ✗ $tabla — NO ENCONTRADA\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Verificar columna tipo en lab_formularios
|
||||
try {
|
||||
$cols = $pdo->query("SHOW COLUMNS FROM lab_formularios LIKE 'tipo'")->fetchAll();
|
||||
if (!empty($cols)) {
|
||||
echo " ✓ lab_formularios.tipo (ENUM)\n";
|
||||
} else {
|
||||
echo " ✗ lab_formularios.tipo — NO SE AGREGÓ\n";
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo " ✗ lab_formularios — " . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
// Verificar prioridades
|
||||
echo "\n🎫 Prioridades insertadas:\n";
|
||||
$prios = $pdo->query("SELECT codigo, nombre, color FROM turnero_prioridades ORDER BY orden_peso")->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($prios as $p) {
|
||||
echo " [{$p['codigo']}] {$p['nombre']} {$p['color']}\n";
|
||||
}
|
||||
|
||||
// Verificar lugares
|
||||
echo "\n📍 Lugares creados:\n";
|
||||
$lugares = $pdo->query("SELECT id, nombre FROM turnero_lugares ORDER BY sort_order")->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($lugares as $l) {
|
||||
echo " [{$l['id']}] {$l['nombre']}\n";
|
||||
}
|
||||
|
||||
// Verificar exámenes de ejemplo
|
||||
echo "\n🧪 Tipos de examen de ejemplo:\n";
|
||||
$exams = $pdo->query("SELECT codigo, nombre, categoria FROM exam_tipos ORDER BY id")->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($exams as $e) {
|
||||
echo " [{$e['codigo']}] {$e['nombre']} — {$e['categoria']}\n";
|
||||
}
|
||||
|
||||
echo "\n✅ Migración 003 lista. Continúa con FASE 3.2 (Motor de cola + API).\n\n";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "❌ Error fatal: " . $e->getMessage() . "\n";
|
||||
exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user