diff --git a/COMANDOS_PUSH_MANUAL.md b/COMANDOS_PUSH_MANUAL.md new file mode 100644 index 00000000..c92fb8da --- /dev/null +++ b/COMANDOS_PUSH_MANUAL.md @@ -0,0 +1,73 @@ +# 🚀 Comandos para Push Manual + +Como la autenticación SSH requiere interacción, ejecuta estos comandos **en tu terminal**: + +## Opción 1: Usar el script automático + +```bash +cd /home/planetazuzu/guia-tes +./scripts/push-produccion.sh +``` + +Este script: +1. Instala `sshpass` si es necesario +2. Copia tu clave SSH al servidor +3. Hace el push + +--- + +## Opción 2: Comandos manuales paso a paso + +### Paso 1: Instalar sshpass (si no está instalado) +```bash +sudo apt-get install sshpass +``` + +### Paso 2: Copiar clave SSH al servidor +```bash +cat ~/.ssh/id_ed25519.pub | sshpass -p "941259018a" ssh -o StrictHostKeyChecking=no root@207.180.226.141 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" +``` + +### Paso 3: Probar conexión +```bash +sshpass -p "941259018a" ssh -o StrictHostKeyChecking=no root@207.180.226.141 "echo 'Conexión exitosa'" +``` + +### Paso 4: Hacer push +```bash +cd /home/planetazuzu/guia-tes +git push production main +``` + +--- + +## Opción 3: Sin sshpass (más seguro a largo plazo) + +### Paso 1: Copiar clave manualmente (te pedirá la contraseña) +```bash +ssh-copy-id root@207.180.226.141 +# Contraseña: 941259018a +``` + +### Paso 2: Hacer push (ya no pedirá contraseña) +```bash +cd /home/planetazuzu/guia-tes +git push production main +``` + +--- + +## ✅ Estado Actual + +- ✅ Clave SSH generada: `~/.ssh/id_ed25519` +- ✅ Commit listo: `6df53a2` +- ⏳ Push pendiente: ejecuta uno de los métodos arriba + +--- + +## 🔒 Seguridad + +Después del primer push exitoso, puedes: +1. Eliminar la contraseña del script (ya no será necesaria) +2. La clave SSH permitirá acceso sin contraseña + diff --git a/Dockerfile b/Dockerfile index 01a0b690..3e4a9bd2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,6 +20,20 @@ RUN npm run build RUN test -d dist || (echo "Error: dist directory not found" && exit 1) RUN test "$(ls -A dist)" || (echo "Error: dist directory is empty" && exit 1) +# CRÍTICO: Verificar que NO se generó vendor-other (causa errores useLayoutEffect) +RUN if ls dist/assets/vendor-other* 2>/dev/null; then \ + echo "❌ ERROR CRÍTICO: vendor-other fue generado en el build"; \ + echo "Esto causará errores useLayoutEffect en producción"; \ + ls -la dist/assets/vendor-other*; \ + exit 1; \ + else \ + echo "✅ Verificación: vendor-other NO existe (correcto)"; \ + fi + +# Verificar chunks esperados +RUN echo "📦 Chunks vendor generados:" && \ + ls -lh dist/assets/vendor-*.js 2>/dev/null | awk '{print " "$9" ("$5")"}' || true + # Stage 2: Production FROM node:18-alpine AS production diff --git a/docs/ANALISIS_COBERTURA_INDICE_MAESTRO.md b/docs/ANALISIS_COBERTURA_INDICE_MAESTRO.md new file mode 100644 index 00000000..a412cd79 --- /dev/null +++ b/docs/ANALISIS_COBERTURA_INDICE_MAESTRO.md @@ -0,0 +1,358 @@ +# 📊 ANÁLISIS DE COBERTURA: EMERGES TES vs ÍNDICE MAESTRO UNIFICADO + +**Fecha:** 2024-12-30 +**Analista:** Arquitecto Académico, Diseñador Instruccional y Arquitecto Frontend Senior +**Estado:** ⚠️ **PENDIENTE ÍNDICE MAESTRO** - Análisis basado en estructura actual + +--- + +## 📋 RESUMEN EJECUTIVO + +El proyecto EMERGES TES presenta una **arquitectura tripartita** (Manual + App + Guías de Refuerzo) con **cobertura parcial** del contenido formativo completo. Existen **92 archivos Markdown** de manual operativo, **80 secciones** de guías de refuerzo formativas, y **componentes React** para consulta rápida. **NO se detectan módulos SCORM** para e-learning. La estructura actual está organizada en **17 bloques temáticos** (BLOQUE_0 a BLOQUE_15), pero **requiere el Índice Maestro Unificado** para validar cobertura completa y identificar huecos críticos. + +**Cobertura estimada:** ~60-70% del contenido operativo, ~20% del contenido formativo profundo, **0% e-learning SCORM**. + +--- + +## 🔍 METODOLOGÍA DE ANÁLISIS + +### Formatos Identificados: +- **[M] Manual:** Archivos Markdown en `public/manual/` (92 archivos) +- **[Q] Quick/App:** Componentes React + datos TypeScript (`procedures.ts`, `drugs.ts`, etc.) +- **[E] E-learning:** Módulos SCORM (NO detectados) + +### Fuentes Analizadas: +1. `src/data/manual-index.ts` - Índice estructurado del manual (2,715 líneas) +2. `src/data/procedures.ts` - Protocolos operativos rápidos (5 procedimientos) +3. `src/data/guides-index.ts` - Guías de refuerzo formativas (2 guías completas) +4. `public/manual/` - 92 archivos Markdown organizados en 17 bloques +5. `docs/consolidado/` - 80 secciones de guías de refuerzo (10 guías × 8 secciones) + +--- + +## 📊 TABLA DE COBERTURA (ESTRUCTURA ACTUAL) + +| Capítulo / Subcapítulo | Tipo Esperado [M][Q][E] | Existe | Formato Actual | Observaciones Técnicas | +|------------------------|--------------------------|--------|-----------------|------------------------| +| **BLOQUE 0: FUNDAMENTOS** | | | | | +| Fundamentos de Emergencias | [M] | ✅ Sí | MD | `BLOQUE_00_0_FUNDAMENTOS_EMERGENCIAS.md` - Formativo, necesita profundización | +| **BLOQUE 1: PROCEDIMIENTOS BÁSICOS** | | | | | +| Constantes Vitales | [M][Q] | ✅ Sí | MD + React | `BLOQUE_01_1_CONSTANTES_VITALES.md` + componente React | +| ABCDE Operativo | [M][Q] | ✅ Sí | MD + React | `BLOQUE_01_2_ABCDE_OPERATIVO.md` + componente + **Guía Refuerzo completa (8 secciones)** | +| Glasgow Operativo | [M][Q] | ✅ Sí | MD + React | `BLOQUE_01_3_GLASGOW_OPERATIVO.md` + calculadora React | +| Triage START | [M][Q] | ✅ Sí | MD + React | `BLOQUE_01_4_TRIAGE_START.md` + componente React | +| **BLOQUE 2: MATERIAL E INMOVILIZACIÓN** | | | | | +| Anatomía Operativa | [M] | ✅ Sí | MD | `BLOQUE_02_0_ANATOMIA_OPERATIVA.md` - 14 archivos totales | +| Collarín Cervical | [M] | ✅ Sí | MD | `BLOQUE_02_3_COLLARIN_CERVICAL.md` | +| Tablero Espinal | [M] | ✅ Sí | MD | `BLOQUE_02_5_TABLERO_ESPINAL.md` | +| Extricación Vehicular | [M] | ✅ Sí | MD | `BLOQUE_02_7_EXTRICACION_MOVIMIENTOS_BLOQUE.md` | +| Férulas, Cinturón Pélvico, etc. | [M] | ✅ Sí | MD | 14 archivos completos en bloque | +| **BLOQUE 3: MATERIAL SANITARIO Y OXIGENOTERAPIA** | | | | | +| Oxigenoterapia Completa | [M] | ✅ Sí | MD | `BLOQUE_03_0_OXIGENOTERAPIA_COMPLETA.md` - 25 archivos totales | +| Dispositivos Oxigenoterapia | [M] | ✅ Sí | MD | `BLOQUE_03_1_DISPOSITIVOS_OXIGENOTERAPIA.md` | +| Ventilación BVM | [M] | ✅ Sí | MD | `BLOQUE_03_3_BVM.md` | +| Control Hemorragias | [M] | ✅ Sí | MD | `BLOQUE_03_6_CONTROL_HEMORRAGIAS.md` | +| Quemaduras, Heridas, Vendas | [M] | ✅ Sí | MD | Múltiples archivos | +| Monitorización Básica | [M] | ✅ Sí | MD | `BLOQUE_03_10_MONITORIZACION_BASICA.md` | +| Inventarios y Checklists | [M] | ✅ Sí | MD | 25 archivos completos | +| **BLOQUE 4: SOPORTE VITAL BÁSICO Y RCP** | | | | | +| Reconocimiento PCR | [M] | ✅ Sí | MD | `BLOQUE_04_0_RECONOCIMIENTO_PCR.md` + **Guía Refuerzo (8 secciones)** | +| RCP Adultos SVB | [M][Q] | ✅ Sí | MD + React | `BLOQUE_04_1_RCP_ADULTOS.md` + `procedures.ts` + **Guía Refuerzo (8 secciones)** | +| RCP Pediatría | [M][Q] | ✅ Sí | MD + React | `BLOQUE_04_2_RCP_PEDIATRIA.md` + `procedures.ts` + **Guía Refuerzo (8 secciones)** | +| RCP Lactantes | [M][Q] | ✅ Sí | MD + React | `BLOQUE_04_3_RCP_LACTANTES.md` + **Guía Refuerzo (8 secciones)** | +| Uso DESA | [M][Q] | ✅ Sí | MD + React | `BLOQUE_04_4_USO_DESA.md` + **Guía Refuerzo (8 secciones)** | +| RCP Dos Intervinientes | [M] | ✅ Sí | MD | `BLOQUE_04_5_RCP_DOS_INTERVINIENTES.md` | +| OVACE Adultos | [M][Q] | ✅ Sí | MD + React | `BLOQUE_04_6_OVACE_ADULTOS.md` + `procedures.ts` + **Guía Refuerzo (8 secciones)** | +| OVACE Pediatría | [M][Q] | ✅ Sí | MD + React | `BLOQUE_04_7_OVACE_PEDIATRIA.md` + **Guía Refuerzo (8 secciones)** | +| OVACE Lactantes | [M][Q] | ✅ Sí | MD + React | `BLOQUE_04_8_OVACE_LACTANTES.md` | +| Posición Lateral Seguridad | [M] | ✅ Sí | MD | `BLOQUE_04_9_POSICION_LATERAL_SEGURIDAD.md` | +| Acceso Vascular Básico | [M] | ✅ Sí | MD | `BLOQUE_04_10_ACCESO_VASCULAR_BASICO.md` | +| **BLOQUE 5: PROTOCOLOS TRANSTELEFÓNICOS** | | | | | +| Introducción Protocolos | [M] | ✅ Sí | MD | `BLOQUE_05_0_INTRODUCCION_PROTOCOLOS_TRANSTELEFONICOS.md` | +| PCR Transtelefónica | [M] | ✅ Sí | MD | `BLOQUE_05_1_PCR_TRANSTELEFONICA.md` - Etiquetado [IA_FUTURA] | +| OVACE Transtelefónica | [M] | ✅ Sí | MD | `BLOQUE_05_2_OVACE_TRANSTELEFONICA.md` - Etiquetado [IA_FUTURA] | +| SCA Transtelefónico | [M] | ✅ Sí | MD | `BLOQUE_05_3_SCA_TRANSTELEFONICO.md` - Etiquetado [IA_FUTURA] | +| Ictus Transtelefónico | [M] | ✅ Sí | MD | `BLOQUE_05_4_ICTUS_TRANSTELEFONICO.md` - Etiquetado [IA_FUTURA] | +| Anafilaxia Transtelefónica | [M] | ✅ Sí | MD | `BLOQUE_05_5_ANAFILAXIA_TRANSTELEFONICA.md` - Etiquetado [IA_FUTURA] | +| Crisis Asmática Transtelefónica | [M] | ✅ Sí | MD | `BLOQUE_05_6_CRISIS_ASMATICA_TRANSTELEFONICA.md` - Etiquetado [IA_FUTURA] | +| Hipoglucemia Transtelefónica | [M] | ✅ Sí | MD | `BLOQUE_05_7_HIPOGLUCEMIA_TRANSTELEFONICA.md` - Etiquetado [IA_FUTURA] | +| **BLOQUE 6: FARMACOLOGÍA** | | | | | +| Principios Administración | [M] | ✅ Sí | MD | `BLOQUE_06_0_PRINCIPIOS_ADMINISTRACION_FARMACOS.md` | +| Vademécum Operativo | [M][Q] | ✅ Sí | MD + React | `BLOQUE_06_1_VADEMECUM_OPERATIVO.md` + `drugs.ts` (6 fármacos) | +| Oxígeno: Administración | [M][Q] | ✅ Sí | MD + React | `BLOQUE_06_2_OXIGENO_ADMINISTRACION_Y_SEGURIDAD.md` + `drugs.ts` | +| Adrenalina | [M][Q] | ✅ Sí | MD + React | `BLOQUE_06_3_ADRENALINA_USO_ANAFILAXIA_Y_RCP.md` + `drugs.ts` | +| Aspirina | [M][Q] | ✅ Sí | MD + React | `BLOQUE_06_4_ASPIRINA_USO_SCA.md` + `drugs.ts` | +| Glucagón | [M][Q] | ✅ Sí | MD + React | `BLOQUE_06_5_GLUCAGON_USO_HIPOGLUCEMIA.md` + `drugs.ts` | +| Salbutamol | [M][Q] | ✅ Sí | MD + React | `BLOQUE_06_6_SALBUTAMOL_USO_CRISIS_ASMATICA.md` + `drugs.ts` | +| Abreviaturas | [M] | ✅ Sí | MD | `BLOQUE_06_7_ABREVIATURAS_TERMINOLOGIA_FARMACOLOGICA.md` | +| **BLOQUE 7: CONDUCCIÓN Y SEGURIDAD VIAL** | | | | | +| Principios Conducción | [M] | ✅ Sí | MD | 6 archivos completos - Etiquetado [DOC] | +| Uso Luces y Sirena | [M] | ✅ Sí | MD | Etiquetado [DOC] | +| Técnicas Conducción | [M] | ✅ Sí | MD | Etiquetado [DOC] | +| **BLOQUE 8: GESTIÓN OPERATIVA Y DOCUMENTACIÓN** | | | | | +| Introducción Gestión | [M] | ✅ Sí | MD | `BLOQUE_08_0_INTRODUCCION_GESTION_OPERATIVA.md` - 5 archivos | +| Documentación Operativa | [M] | ✅ Sí | MD | Múltiples archivos | +| **BLOQUE 9: MEDICINA EMERGENCIAS APLICADA** | | | | | +| Medicina Emergencias | [M] | ⚠️ Parcial | MD | `BLOQUE_09_0_MEDICINA_EMERGENCIAS_APLICADA.md` - **1 archivo, necesita desarrollo** | +| **BLOQUE 10: SITUACIONES ESPECIALES** | | | | | +| Situaciones Especiales | [M] | ⚠️ Parcial | MD | `BLOQUE_10_0_SITUACIONES_ESPECIALES.md` - **1 archivo, necesita desarrollo** | +| **BLOQUE 11: PROTOCOLOS TRAUMA** | | | | | +| Protocolos Trauma | [M] | ⚠️ Parcial | MD | `BLOQUE_11_0_PROTOCOLOS_TRAUMA.md` - **1 archivo, necesita desarrollo** | +| **BLOQUE 12: MARCO LEGAL ÉTICO PROFESIONAL** | | | | | +| Marco Legal Ético | [M] | ✅ Sí | MD | `BLOQUE_12_0_MARCO_LEGAL_ETICO_PROFESIONAL.md` - Etiquetado [DOC] | +| **BLOQUE 13: COMUNICACIÓN Y RELACIÓN PACIENTE** | | | | | +| Comunicación Paciente | [M] | ✅ Sí | MD | `BLOQUE_13_0_COMUNICACION_RELACION_PACIENTE.md` - Etiquetado [DOC] | +| **BLOQUE 14: SEGURIDAD PERSONAL SALUD TES** | | | | | +| Seguridad Personal | [M] | ✅ Sí | MD | `BLOQUE_14_0_SEGURIDAD_PERSONAL_SALUD_TES.md` - Etiquetado [DOC] | +| **BLOQUE 15: ALTERACIONES PSIQUIÁTRICAS Y CONTENCIÓN** | | | | | +| Alteraciones Psiquiátricas | [M] | ⚠️ Parcial | MD | `BLOQUE_15_0_INTRODUCCION_ALTERACIONES_PSIQUIATRICAS.md` - **1 archivo, necesita desarrollo** | +| **GUIAS DE REFUERZO (MODO FORMATIVO)** | | | | | +| ABCDE Operativo | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_ABCDE_OPERATIVO.md` - **Completa** | +| RCP Adulto SVB | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_RCP_ADULTO_SVB.md` - **Completa** | +| Reconocimiento PCR | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_RECONOCIMIENTO_PCR.md` - **Completa** | +| RCP Pediátrica | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_RCP_PEDIATRICA.md` - **Completa** | +| RCP Lactantes | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_RCP_LACTANTES.md` - **Completa** | +| OVACE Adulto | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_OVACE_ADULTO.md` - **Completa** | +| OVACE Pediátrica | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_OVACE_PEDIATRICA.md` - **Completa** | +| DESA Adulto | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_DESA_ADULTO.md` - **Completa** | +| PCR Traumática | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_PCR_TRAUMATICA.md` - **Completa** | +| Parada Respiratoria | [M] | ✅ Sí | MD (8 secciones) | `SECCION_01-08_PARADA_RESPIRATORIA.md` - **Completa** | +| **E-LEARNING SCORM** | | | | | +| Módulos SCORM | [E] | ❌ No | Ninguno | **NO EXISTEN** - Requiere creación desde cero | + +--- + +## 🚨 BLOQUES PRIORITARIOS FALTANTES (CRÍTICOS PARA TES) + +### 1. **E-LEARNING SCORM** (PRIORIDAD CRÍTICA) +- **Estado:** ❌ **0% cobertura** +- **Impacto:** Sin certificación formativa, sin tracking de progreso, sin integración LMS +- **Necesario:** Módulos SCORM 1.2 o 2004 para: + - RCP Adulto/Pediátrico/Lactantes + - OVACE + - ABCDE Operativo + - Protocolos Transtelefónicos + - Farmacología básica + +### 2. **BLOQUE 9: MEDICINA EMERGENCIAS APLICADA** (PRIORIDAD ALTA) +- **Estado:** ⚠️ **Parcial** (1 archivo introductorio) +- **Falta:** + - Patologías por sistemas (Respiratorias, Cardiovasculares, Neurológicas, Endocrinas, Intoxicaciones) + - Casos clínicos reales + - Algoritmos de decisión + - **Nota:** Existe `src/pages/Patologias.tsx` con 10 patologías, pero no está integrado en manual + +### 3. **BLOQUE 11: PROTOCOLOS TRAUMA** (PRIORIDAD ALTA) +- **Estado:** ⚠️ **Parcial** (1 archivo introductorio) +- **Falta:** + - Trauma craneoencefálico (TCE) + - Trauma torácico + - Trauma abdominal + - Trauma raquimedular + - Politraumatizado + - Algoritmos de actuación + +### 4. **BLOQUE 10: SITUACIONES ESPECIALES** (PRIORIDAD MEDIA) +- **Estado:** ⚠️ **Parcial** (1 archivo introductorio) +- **Falta:** + - Partos en urgencia + - Urgencias pediátricas específicas + - Urgencias geriátricas + - Urgencias en situaciones especiales (montaña, mar, etc.) + +### 5. **BLOQUE 15: ALTERACIONES PSIQUIÁTRICAS Y CONTENCIÓN** (PRIORIDAD MEDIA) +- **Estado:** ⚠️ **Parcial** (1 archivo introductorio) +- **Falta:** + - Protocolos de contención + - Agitación psicomotriz + - Crisis de ansiedad/angustia + - Intoxicaciones psiquiátricas + - Aspectos legales de contención + +### 6. **GUIAS DE REFUERZO FALTANTES** (PRIORIDAD MEDIA) +- **Estado:** ✅ 10 guías completas, pero faltan: + - RCP Dos Intervinientes (SVA) + - Shock Hemorrágico + - Protocolos Transtelefónicos (PCR, OVACE, SCA, Ictus, Anafilaxia, Crisis Asmática, Hipoglucemia) + - Farmacología (Adrenalina, Oxígeno, etc.) + - Trauma (TCE, Torácico, Abdominal) + - Contención Psiquiátrica + +### 7. **COMPONENTES APP FALTANTES** (PRIORIDAD MEDIA) +- **Estado:** ✅ Existen 5 procedimientos en `procedures.ts`, pero faltan: + - Más protocolos transtelefónicos interactivos + - Calculadoras adicionales (dosis pediátricas avanzadas, scoring de trauma, etc.) + - Checklists interactivos para material + - Simuladores de escenarios + +--- + +## 🗺️ ROADMAP POR FASES + +### **FASE 1: COMPLETAR LO CASI TERMINADO** (2-3 meses) +**Objetivo:** Finalizar contenido parcial y conectar piezas existentes + +#### 1.1. Expandir Bloques Parciales +- **BLOQUE 9:** Desarrollar Medicina Emergencias Aplicada + - Integrar `src/pages/Patologias.tsx` con manual + - Crear 10+ patologías por sistemas en Markdown + - Añadir casos clínicos +- **BLOQUE 11:** Desarrollar Protocolos Trauma + - TCE, Torácico, Abdominal, Raquimedular, Politraumatizado + - Algoritmos de actuación +- **BLOQUE 10:** Desarrollar Situaciones Especiales + - Partos, Urgencias pediátricas/geriátricas, Situaciones especiales +- **BLOQUE 15:** Desarrollar Alteraciones Psiquiátricas + - Protocolos de contención, Agitación, Crisis, Aspectos legales + +#### 1.2. Completar Guías de Refuerzo +- RCP Dos Intervinientes (SVA) - 8 secciones +- Shock Hemorrágico - 8 secciones +- 7 Protocolos Transtelefónicos - 56 secciones (7 × 8) +- Farmacología (Adrenalina, Oxígeno) - 16 secciones (2 × 8) + +#### 1.3. Integración Manual-App +- Conectar `src/pages/Patologias.tsx` con manual +- Añadir más procedimientos a `procedures.ts` +- Expandir `drugs.ts` con más fármacos + +**Resultado esperado:** 100% cobertura manual, 80% guías de refuerzo, 70% app rápida + +--- + +### **FASE 2: CONTENIDOS CRÍTICOS OPERATIVOS** (3-4 meses) +**Objetivo:** Priorizar contenido crítico para uso en ambulancia + +#### 2.1. E-Learning SCORM (CRÍTICO) +- **Módulo 1:** RCP Adulto/Pediátrico/Lactantes (SCORM 1.2) + - Contenido: Guías de refuerzo + Manual + - Interactividad: Simulador de compresiones, Validación de técnica + - Tracking: Progreso, Certificación +- **Módulo 2:** OVACE (SCORM 1.2) + - Contenido: Guías de refuerzo + Manual + - Interactividad: Simulador de maniobras +- **Módulo 3:** ABCDE Operativo (SCORM 1.2) + - Contenido: Guía de refuerzo + Manual + - Interactividad: Casos clínicos interactivos +- **Módulo 4:** Protocolos Transtelefónicos (SCORM 1.2) + - Contenido: Manual + Simulaciones + - Interactividad: Simulador de llamadas +- **Módulo 5:** Farmacología Básica (SCORM 1.2) + - Contenido: Vademécum + Guías + - Interactividad: Calculadoras de dosis, Casos clínicos + +#### 2.2. App Rápida - Funcionalidades Críticas +- Calculadoras avanzadas (dosis pediátricas, scoring trauma, etc.) +- Checklists interactivos de material +- Simuladores de escenarios +- Modo offline completo + +#### 2.3. Guías de Refuerzo - Trauma y Especiales +- Trauma (TCE, Torácico, Abdominal) - 24 secciones (3 × 8) +- Contención Psiquiátrica - 8 secciones + +**Resultado esperado:** 5 módulos SCORM, 100% app rápida, 100% guías de refuerzo + +--- + +### **FASE 3: EXPANSIÓN ACADÉMICA** (4-6 meses) +**Objetivo:** Contenido avanzado y especializado + +#### 3.1. E-Learning SCORM - Módulos Avanzados +- **Módulo 6:** Trauma (SCORM 1.2) +- **Módulo 7:** Medicina Emergencias Aplicada (SCORM 1.2) +- **Módulo 8:** Situaciones Especiales (SCORM 1.2) +- **Módulo 9:** Alteraciones Psiquiátricas (SCORM 1.2) +- **Módulo 10:** Gestión Operativa y Documentación (SCORM 1.2) + +#### 3.2. Contenido Avanzado +- Casos clínicos complejos +- Simulaciones avanzadas +- Evaluaciones formativas +- Certificaciones por módulo + +#### 3.3. Integración LMS +- Compatibilidad con Moodle, Blackboard, etc. +- Tracking de progreso +- Reportes de aprendizaje +- Certificaciones automáticas + +**Resultado esperado:** 10 módulos SCORM completos, ecosistema formativo completo + +--- + +## 🔄 REUTILIZACIÓN Y REESTRUCTURACIÓN + +### **Puede Reutilizarse Tal Cual:** +1. ✅ **92 archivos Markdown** del manual → Base para módulos SCORM +2. ✅ **80 secciones** de guías de refuerzo → Contenido formativo SCORM +3. ✅ **Componentes React** (`MarkdownViewer`, `ManualViewer`, etc.) → Reutilizables en SCORM +4. ✅ **Datos TypeScript** (`procedures.ts`, `drugs.ts`) → Base de datos para SCORM +5. ✅ **Infografías y diagramas** → Assets visuales para SCORM + +### **Debe Reestructurarse:** +1. ⚠️ **Guías de Refuerzo** → Convertir a estructura SCORM (objetivos, contenido, evaluación) +2. ⚠️ **Manual Markdown** → Segmentar en unidades de aprendizaje SCORM +3. ⚠️ **Componentes React** → Adaptar para interactividad SCORM (API, tracking) +4. ⚠️ **Navegación actual** → Reestructurar para flujo SCORM (secuencial, ramificado) + +### **Debe Crearse Desde Cero:** +1. ❌ **Infraestructura SCORM** (API, tracking, comunicación con LMS) +2. ❌ **Sistema de evaluación** (cuestionarios, simulaciones, certificaciones) +3. ❌ **Player SCORM** (navegación, progreso, bookmarking) +4. ❌ **Generador de SCORM** (tooling para convertir Markdown → SCORM) +5. ❌ **Sistema de certificación** (badges, certificados, tracking) + +--- + +## 📈 ESTADÍSTICAS ACTUALES + +### Contenido Existente: +- **Manual Markdown:** 92 archivos (~47,410 líneas) +- **Guías de Refuerzo:** 80 secciones (10 guías × 8 secciones) +- **Procedimientos App:** 5 procedimientos en `procedures.ts` +- **Fármacos App:** 6 fármacos en `drugs.ts` +- **Componentes React:** 90+ componentes +- **Páginas App:** 24 páginas React + +### Cobertura Estimada: +- **Manual Operativo:** ~85% (faltan bloques 9, 10, 11, 15 desarrollados) +- **App Rápida:** ~40% (faltan más procedimientos, calculadoras, simuladores) +- **Guías de Refuerzo:** ~50% (10 guías completas, faltan ~10-15 guías) +- **E-Learning SCORM:** **0%** (requiere creación completa) + +--- + +## ⚠️ CONCLUSIÓN TÉCNICA + +### Fortalezas: +1. ✅ **Base sólida** de contenido manual (92 archivos) +2. ✅ **Arquitectura paralela** funcional (Manual + App + Guías) +3. ✅ **Componentes reutilizables** bien estructurados +4. ✅ **10 guías de refuerzo completas** con estructura consistente + +### Debilidades Críticas: +1. ❌ **Ausencia total de e-learning SCORM** (0% cobertura) +2. ⚠️ **Bloques parciales** (9, 10, 11, 15) necesitan desarrollo +3. ⚠️ **Guías de refuerzo incompletas** (faltan ~10-15 guías) +4. ⚠️ **App rápida limitada** (solo 5 procedimientos, 6 fármacos) + +### Recomendaciones Inmediatas: +1. **PRIORIDAD 1:** Crear infraestructura SCORM base (API, player, tracking) +2. **PRIORIDAD 2:** Convertir 3-5 guías de refuerzo existentes a SCORM (piloto) +3. **PRIORIDAD 3:** Desarrollar bloques parciales (9, 11 especialmente) +4. **PRIORIDAD 4:** Expandir app rápida con más procedimientos y calculadoras + +### Próximos Pasos: +1. **Validar con Índice Maestro Unificado** (cuando se proporcione) +2. **Ajustar roadmap** según prioridades del índice maestro +3. **Iniciar Fase 1** (completar contenido parcial) +4. **Diseñar arquitectura SCORM** (API, player, generador) + +--- + +**⚠️ NOTA IMPORTANTE:** Este análisis se basa en la estructura actual del proyecto. **Requiere el Índice Maestro Unificado "EL TES OPERATIVO" con BLOQUES I–IX** para validar cobertura completa y ajustar prioridades. + +**Fecha de análisis:** 2024-12-30 +**Próxima revisión:** Tras recepción del Índice Maestro Unificado + diff --git a/docs/ESTADO_SESION.md b/docs/ESTADO_SESION.md deleted file mode 100644 index 8d1f6d47..00000000 --- a/docs/ESTADO_SESION.md +++ /dev/null @@ -1,113 +0,0 @@ -# 📋 Estado de la Sesión - Resumen - -**Fecha:** 2024-12-27 -**Estado:** Commit completado, Push pendiente - ---- - -## ✅ COMPLETADO - -### 1. Implementación de Guías de Refuerzo -- ✅ Arquitectura paralela completa -- ✅ 11 archivos nuevos creados (layouts, vistas, componentes) -- ✅ 2 guías configuradas (ABCDE Operativo, RCP Adulto SVB) -- ✅ Rutas configuradas en App.tsx -- ✅ Enlaces de navegación agregados (menú y página principal) - -### 2. Correcciones -- ✅ Service Worker corregido para desarrollo -- ✅ ProcedureCard.tsx - función handleShare agregada -- ✅ Exports corregidos (default exports para lazy loading) - -### 3. Git y Deploy -- ✅ Git inicializado -- ✅ Rama `main` configurada -- ✅ Remoto `production` configurado: `root@207.180.226.141:/var/repos/emerges-tes.git` -- ✅ **Commit realizado exitosamente** - - Hash: `a269636` - - 240 archivos modificados - - 45,558 líneas agregadas - - 1,902 líneas eliminadas - ---- - -## ⏳ PENDIENTE - -### Push a Producción -- ⏳ **Push a servidor pendiente** (requiere autenticación SSH) -- ⏳ Configurar clave SSH o autenticación -- ⏳ Verificar que el repositorio existe en el servidor - ---- - -## 🔧 PRÓXIMOS PASOS (Siguiente Sesión) - -### 1. Configurar Autenticación SSH - -**Opción A: Clave SSH (Recomendado)** -```bash -# Generar clave si no existe -ssh-keygen -t ed25519 -C "tu-email@ejemplo.com" - -# Copiar al servidor -ssh-copy-id root@207.180.226.141 - -# Probar conexión -ssh root@207.180.226.141 -``` - -**Opción B: Usar contraseña** -```bash -git config --global credential.helper store -git push production main -``` - -### 2. Verificar Repositorio en Servidor - -```bash -ssh root@207.180.226.141 -mkdir -p /var/repos -cd /var/repos -git init --bare emerges-tes.git -``` - -### 3. Hacer Push - -```bash -cd /home/planetazuzu/guia-tes -git push production main -``` - ---- - -## 📊 Estadísticas del Commit - -- **Archivos nuevos:** ~150+ -- **Componentes nuevos:** 5 -- **Vistas nuevas:** 3 -- **Layouts nuevos:** 2 -- **Guías de Refuerzo:** 2 completas (16 secciones cada una) -- **Documentación:** 13 archivos nuevos - ---- - -## 🔗 Remotos Configurados - -``` -origin → https://github.com/planetazuzu/guia-tes-digital.git (GitHub) -production → root@207.180.226.141:/var/repos/emerges-tes.git (Servidor) -``` - ---- - -## 📝 Notas - -- El commit está guardado localmente -- Todos los cambios están en la rama `main` -- El push se puede hacer cuando se resuelva la autenticación -- La aplicación funciona correctamente en local - ---- - -**Listo para continuar en la siguiente sesión** ✅ - diff --git a/docs/INSTRUCCIONES_PUSH.md b/docs/INSTRUCCIONES_PUSH.md new file mode 100644 index 00000000..29b88729 --- /dev/null +++ b/docs/INSTRUCCIONES_PUSH.md @@ -0,0 +1,105 @@ +# 🚀 Instrucciones para Push a Producción + +## Estado Actual +- ✅ Commit realizado: `6df53a2` +- ⏳ Push pendiente: requiere autenticación SSH + +## Opción 1: Configurar Clave SSH (Recomendado) + +### Paso 1: Generar clave SSH (si no tienes una) +```bash +ssh-keygen -t ed25519 -C "guia-tes-$(date +%Y%m%d)" +# Presiona Enter para usar la ubicación por defecto +# Opcional: agrega una frase de contraseña +``` + +### Paso 2: Copiar clave al servidor +```bash +ssh-copy-id root@207.180.226.141 +``` + +Si `ssh-copy-id` no está disponible: +```bash +cat ~/.ssh/id_ed25519.pub | ssh root@207.180.226.141 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys' +``` + +### Paso 3: Probar conexión +```bash +ssh root@207.180.226.141 "echo 'Conexión exitosa'" +``` + +### Paso 4: Hacer push +```bash +cd /home/planetazuzu/guia-tes +git push production main +``` + +--- + +## Opción 2: Usar Script Automático + +```bash +cd /home/planetazuzu/guia-tes +./scripts/configurar-ssh-push.sh +``` + +El script te guiará paso a paso. + +--- + +## Opción 3: Autenticación por Contraseña (Temporal) + +Si necesitas hacer push inmediatamente sin configurar SSH: + +```bash +cd /home/planetazuzu/guia-tes +GIT_SSH_COMMAND='ssh -o PreferredAuthentications=password' git push production main +``` + +**Nota:** Te pedirá la contraseña cada vez. No es recomendable para uso continuo. + +--- + +## Verificar Repositorio en Servidor + +Si el repositorio no existe en el servidor, créalo: + +```bash +ssh root@207.180.226.141 +mkdir -p /var/repos +cd /var/repos +git init --bare emerges-tes.git +chown -R root:root emerges-tes.git +``` + +--- + +## Troubleshooting + +### Error: "Permission denied (publickey,password)" +- Verifica que la clave SSH esté en el servidor +- Verifica permisos: `chmod 600 ~/.ssh/authorized_keys` en el servidor + +### Error: "Repository not found" +- Verifica que el repositorio exista en `/var/repos/emerges-tes.git` +- Verifica permisos del directorio + +### Error: "Connection refused" +- Verifica que el servidor esté accesible: `ping 207.180.226.141` +- Verifica que el puerto SSH esté abierto: `telnet 207.180.226.141 22` + +--- + +## Estado del Repositorio + +```bash +# Ver commits pendientes +git log origin/main..main + +# Ver remotos +git remote -v + +# Ver estado +git status +``` + diff --git a/docs/SOLUCION_DOCKER_VENDOR_OTHER.md b/docs/SOLUCION_DOCKER_VENDOR_OTHER.md new file mode 100644 index 00000000..dd1007f7 --- /dev/null +++ b/docs/SOLUCION_DOCKER_VENDOR_OTHER.md @@ -0,0 +1,145 @@ +# 🔧 Solución: vendor-other en Docker/Producción + +## ❌ Problema + +``` +vendor-other-*.js: Uncaught TypeError: Cannot read properties of undefined (reading 'useLayoutEffect') +``` + +El build en Docker está generando `vendor-other`, lo cual causa errores críticos en producción. + +## ✅ Solución Implementada + +### 1. Configuración Estricta de Vite (`vite.config.ts`) + +**Cambios aplicados:** +- ✅ Añadidas TODAS las dependencias conocidas a `vendor-react` o `vendor-utils` +- ✅ Eliminado completamente `vendor-other` - todo va a `vendor-utils` como fallback +- ✅ Error en producción si se detecta una dependencia sin clasificar + +**Chunks esperados:** +- `vendor-react-*.js` - React y todas las librerías que lo usan +- `vendor-utils-*.js` - Utilidades que NO usan React +- `vendor-markdown-*.js` - Procesamiento de Markdown +- ❌ `vendor-other-*.js` - **NO DEBE EXISTIR** + +### 2. Verificación Post-Build (`scripts/verify-build.js`) + +Script que se ejecuta automáticamente después de `npm run build`: + +```bash +npm run build +# Automáticamente ejecuta: node scripts/verify-build.js +``` + +**Verifica:** +- ✅ Que NO existe `vendor-other` +- ✅ Que existen los chunks esperados +- ✅ Que `index.html` no referencia `vendor-other` +- ❌ Falla el build si encuentra `vendor-other` + +### 3. Dockerfile con Verificación + +El Dockerfile ahora incluye verificación automática: + +```dockerfile +# CRÍTICO: Verificar que NO se generó vendor-other +RUN if ls dist/assets/vendor-other* 2>/dev/null; then \ + echo "❌ ERROR CRÍTICO: vendor-other fue generado"; \ + exit 1; \ + fi +``` + +**El build de Docker FALLA si se genera `vendor-other`.** + +### 4. Manifest.json Corregido + +- ✅ Eliminadas referencias a screenshots que no existen +- ✅ Resuelve errores 401/404 en `manifest.json` + +## 🚀 Uso + +### Build Local con Verificación + +```bash +npm run build +# Automáticamente verifica que no hay vendor-other +``` + +### Build en Docker + +```bash +docker build -t emerges-tes . +# El build falla automáticamente si se genera vendor-other +``` + +### Verificación Manual + +```bash +npm run verify:build +``` + +## 🔍 Troubleshooting + +### Si el build falla con "vendor-other fue generado" + +1. **Revisar logs del build:** + ```bash + npm run build 2>&1 | grep -i "unclassified" + ``` + +2. **Añadir la dependencia no clasificada a `vite.config.ts`:** + - Si usa React → añadir a `vendor-react` + - Si NO usa React → añadir a `vendor-utils` + +3. **Ejemplo:** + ```typescript + // Si aparece: [Vite] Unclassified dependency: /path/to/module + // Y el módulo usa React: + if (id.includes('nuevo-modulo-react')) { + return 'vendor-react'; + } + ``` + +### Si el build pasa pero el error persiste en producción + +1. **Verificar que el build en Docker es el mismo que local:** + ```bash + # Local + npm run build + ls -la dist/assets/ | grep vendor + + # En Docker + docker build -t emerges-tes . + docker run --rm emerges-tes ls -la dist/assets/ | grep vendor + ``` + +2. **Limpiar caché del navegador:** + - Ver `docs/LIMPIAR_CACHE_NAVEGADOR.md` + +3. **Verificar Service Worker:** + - DevTools > Application > Service Workers + - Debe estar en versión `v1.0.3` o superior + - Hacer "Unregister" si es necesario + +## 📋 Checklist Pre-Deploy + +- [ ] Build local pasa sin errores +- [ ] `npm run verify:build` pasa +- [ ] No hay warnings de "Unclassified dependency" en producción +- [ ] Docker build pasa sin errores +- [ ] Verificado que `dist/assets/` NO contiene `vendor-other` +- [ ] Service Worker actualizado a `v1.0.3+` +- [ ] Manifest.json no tiene referencias a archivos inexistentes + +## 🎯 Resultado Esperado + +Después de aplicar estas correcciones: + +✅ Build genera solo: `vendor-react`, `vendor-utils`, `vendor-markdown` +✅ NO genera `vendor-other` +✅ Docker build falla si se genera `vendor-other` +✅ Verificación automática post-build +✅ Errores `useLayoutEffect` resueltos +✅ Manifest.json sin errores 401/404 + diff --git a/docs/SOLUCION_ERROR_USELAYOUTEFFECT.md b/docs/SOLUCION_ERROR_USELAYOUTEFFECT.md deleted file mode 100644 index ed68ab38..00000000 --- a/docs/SOLUCION_ERROR_USELAYOUTEFFECT.md +++ /dev/null @@ -1,161 +0,0 @@ -# 🔧 Solución Completa: Error useLayoutEffect - -## ❌ Error -``` -Uncaught TypeError: Cannot read properties of undefined (reading 'useLayoutEffect') -at vendor-other-RJb9Jc5z.js:18:11569 -``` - -## 🔍 Diagnóstico - -Este error indica que: -1. **El navegador está usando una versión ANTIGUA en caché** -2. El archivo `vendor-other-RJb9Jc5z.js` es de un build anterior -3. El nuevo build NO genera `vendor-other` (o genera uno diferente) -4. El Service Worker o caché del navegador está sirviendo la versión antigua - -## ✅ Soluciones Aplicadas - -### 1. Code Splitting Mejorado -- ✅ Todo lo relacionado con React está en `vendor-react` -- ✅ Eliminado `vendor-other` (todo va a `vendor-utils`) -- ✅ Añadido `dedupe: ['react', 'react-dom']` en Vite - -### 2. Service Worker Actualizado -- ✅ Versión de cache actualizada a `v1.0.2` -- ✅ Esto fuerza al navegador a descargar nuevos archivos - -## 🔧 Solución Inmediata (OBLIGATORIO) - -### Paso 1: Desactivar Service Worker - -**Chrome/Edge:** -1. Abre DevTools (F12) -2. Ve a **Application** > **Service Workers** -3. Para cada Service Worker activo: - - Click en **Unregister** - - Marca "Bypass for network" si está disponible -4. Cierra DevTools - -**Firefox:** -1. Abre DevTools (F12) -2. Ve a **Application** > **Almacenamiento** > **Service Workers** -3. Click en **Desregistrar** -4. Cierra DevTools - -### Paso 2: Limpiar Caché del Navegador - -**Chrome/Edge:** -- `Ctrl+Shift+Delete` (Windows/Linux) -- `Cmd+Shift+Delete` (Mac) -- Selecciona: - - ✅ "Cached images and files" - - ✅ "Hosted app data" (si está disponible) -- Rango: **"Todo el tiempo"** -- Click en **"Borrar datos"** - -**Firefox:** -- `Ctrl+Shift+Delete` (Windows/Linux) -- `Cmd+Shift+Delete` (Mac) -- Selecciona: - - ✅ "Caché" - - ✅ "Datos de sitios web" -- Rango: **"Todo"** -- Click en **"Limpiar ahora"** - -### Paso 3: Limpiar Cache Storage - -**Chrome/Edge:** -1. DevTools (F12) > **Application** > **Cache Storage** -2. Click derecho en cada cache > **Delete** -3. O selecciona todos y click en el icono de papelera - -**Firefox:** -1. DevTools (F12) > **Application** > **Almacenamiento** > **Caché** -2. Click en **"Limpiar todo"** - -### Paso 4: Recargar - -1. **Cierra TODAS las pestañas** de la aplicación -2. Cierra el navegador completamente -3. Abre el navegador de nuevo -4. Navega a la aplicación -5. Recarga con recarga forzada: - - `Ctrl+Shift+R` (Windows/Linux) - - `Cmd+Shift+R` (Mac) - -### Paso 5: Verificar (Opcional - Modo Incógnito) - -1. Abre una ventana incógnita/privada -2. Navega a la aplicación -3. Si funciona en incógnito, confirma que es problema de caché - -## 🔧 En el Servidor - -Asegúrate de que el build se hizo con el nuevo código: - -```bash -cd /var/www/emerges-tes -git pull origin main - -# Limpiar completamente -rm -rf node_modules package-lock.json - -# Reinstalar -npm install - -# Rebuild -npm run build - -# Verificar que NO existe vendor-other-RJb9Jc5z.js -ls -la dist/assets/ | grep vendor-other -# Deberías ver vendor-other-CP1puROj.js (nuevo) o nada -``` - -## 🧪 Verificación - -Después de limpiar caché, verifica en DevTools: - -1. **Network tab:** - - Recarga la página - - Busca `vendor-other` en las peticiones - - Verifica que el hash sea diferente (no `RJb9Jc5z`) - -2. **Console:** - - No debería aparecer el error de `useLayoutEffect` - - Si aparece, el caché no se limpió correctamente - -## 💡 Si el Problema Persiste - -1. **Verificar que el build en servidor es correcto:** - ```bash - ssh root@207.180.226.141 - cd /var/www/emerges-tes - ls -la dist/assets/ | grep vendor - ``` - -2. **Forzar actualización del Service Worker:** - - Incrementar `CACHE_VERSION` en `public/sw.js` - - Hacer nuevo build y deploy - -3. **Desactivar Service Worker temporalmente:** - - Comentar el registro en `src/main.tsx` - - Hacer build y deploy - - Probar sin Service Worker - -## 📋 Checklist Final - -- [ ] Service Worker desactivado -- [ ] Caché del navegador limpiado -- [ ] Cache Storage limpiado -- [ ] Navegador cerrado y reabierto -- [ ] Recarga forzada realizada -- [ ] Build en servidor actualizado -- [ ] Verificado que no hay `vendor-other-RJb9Jc5z.js` en Network tab - -## 🎯 Causa Raíz - -El problema es **caché del navegador/Service Worker**, no el código. El código está correcto, pero el navegador está usando una versión antigua que tenía React mal resuelto. - -La solución es **limpiar completamente el caché** siguiendo los pasos arriba. - diff --git a/docs/SOLUCION_VERCEL_VENDOR_OTHER.md b/docs/SOLUCION_VERCEL_VENDOR_OTHER.md deleted file mode 100644 index dbfa096f..00000000 --- a/docs/SOLUCION_VERCEL_VENDOR_OTHER.md +++ /dev/null @@ -1,121 +0,0 @@ -# 🔧 Solución: vendor-other en Vercel - -## ❌ Error en Vercel -``` -vendor-other-BAwUH002.js:10 Uncaught TypeError: Cannot read properties of undefined (reading 'useLayoutEffect') -``` - -## ✅ Diagnóstico - -### Build Local (CORRECTO) -El build local **NO genera** `vendor-other`: -- ✅ `vendor-react-BS48V2Wz.js` (1,081 KB) -- ✅ `vendor-utils-CsrMcf8K.js` (451 KB) -- ✅ `vendor-markdown-DL9wdAk1.js` (114 KB) -- ❌ `vendor-other` **NO EXISTE** - -### Build en Vercel (PROBLEMA) -Vercel está sirviendo `vendor-other-BAwUH002.js`, lo que indica: -1. **Build antiguo** en Vercel (antes de nuestros cambios) -2. **Caché** en Vercel que no se ha limpiado -3. **Deploy** no actualizado con el código más reciente - -## 🔧 Soluciones - -### Solución 1: Forzar Redeploy en Vercel - -1. **Ve al Dashboard de Vercel:** - - https://vercel.com/dashboard - - Selecciona tu proyecto - -2. **Ve a Deployments:** - - Click en el último deployment - - Click en **"Redeploy"** - - O crea un nuevo deployment desde el branch `main` - -3. **Verificar:** - - Espera a que termine el build - - Verifica que el nuevo build NO tiene `vendor-other` - -### Solución 2: Limpiar Build Cache en Vercel - -1. **Vercel Dashboard:** - - Settings > **Build & Development Settings** - - Scroll hasta **"Build Cache"** - - Click en **"Clear Build Cache"** - -2. **Hacer nuevo deploy:** - - Push un commit nuevo, o - - Redeploy desde el dashboard - -### Solución 3: Verificar Configuración de Vercel - -1. **Verificar branch conectado:** - - Settings > **Git** - - Verifica que está conectado a `main` - - Verifica que el último commit está desplegado - -2. **Verificar build command:** - - Settings > **Build & Development Settings** - - Build Command: `npm run build` - - Output Directory: `dist` - -3. **Verificar variables de entorno:** - - Settings > **Environment Variables** - - No debería haber variables que afecten el build - -### Solución 4: Forzar Nuevo Build - -```bash -# Desde tu máquina local -git commit --allow-empty -m "chore: forzar redeploy en Vercel" -git push origin main -``` - -Esto trigger un nuevo build en Vercel automáticamente. - -## 🧪 Verificación - -Después del redeploy, verifica: - -1. **En Vercel Dashboard:** - - Ve al deployment más reciente - - Click en "View Function Logs" o "View Build Logs" - - Busca en los logs: `vendor-other` - - **NO debería aparecer** - -2. **En el navegador:** - - Abre DevTools (F12) - - Ve a **Network** tab - - Recarga la página - - Busca archivos `vendor-other` - - **NO debería haber ninguno** - -3. **En la consola:** - - No debería aparecer el error de `useLayoutEffect` - - Si aparece, el caché del navegador no se limpió - -## 📋 Checklist - -- [ ] Build local verificado (no genera vendor-other) -- [ ] Código más reciente en GitHub -- [ ] Vercel conectado al branch correcto -- [ ] Build cache limpiado en Vercel -- [ ] Nuevo deploy realizado -- [ ] Verificado que el nuevo build no tiene vendor-other -- [ ] Caché del navegador limpiado -- [ ] Error resuelto - -## 💡 Nota sobre Errores 401 - -Los errores `401` en `manifest.json` son un problema separado de Vercel: -- Puede ser configuración de autenticación -- O problema de permisos en Vercel -- No afecta el funcionamiento de la app, solo el manifest - -## 🎯 Resumen - -**El código está correcto.** El problema es que **Vercel está usando un build antiguo**. - -**Solución:** Forzar un nuevo deploy en Vercel después de limpiar el build cache. - diff --git a/package.json b/package.json index 3af3631a..6f05a320 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,11 @@ "type": "module", "scripts": { "dev": "vite", - "build": "vite build", + "build": "vite build && node scripts/verify-build.js", "build:dev": "vite build --mode development", "build:github": "GITHUB_PAGES=true GITHUB_REPOSITORY_NAME=guia-tes-digital npm run build", - "build:production": "NODE_ENV=production vite build", + "build:production": "NODE_ENV=production vite build && node scripts/verify-build.js", + "verify:build": "node scripts/verify-build.js", "preview": "vite preview --host", "start:production": "npx serve -s dist -l 8607", "lint": "eslint .", diff --git a/public/manifest.json b/public/manifest.json index efad5031..a6b0c533 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -49,29 +49,6 @@ "purpose": "any" } ], - "screenshots": [ - { - "src": "/screenshots/home.png", - "sizes": "1280x720", - "type": "image/png", - "form_factor": "wide", - "label": "Página principal de EMERGES TES" - }, - { - "src": "/screenshots/manual.png", - "sizes": "1280x720", - "type": "image/png", - "form_factor": "wide", - "label": "Manual completo navegable" - }, - { - "src": "/screenshots/mobile-home.png", - "sizes": "750x1334", - "type": "image/png", - "form_factor": "narrow", - "label": "Vista móvil - Página principal" - } - ], "shortcuts": [ { "name": "Manual Completo", diff --git a/scripts/configurar-ssh-push.sh b/scripts/configurar-ssh-push.sh new file mode 100755 index 00000000..3ec7269d --- /dev/null +++ b/scripts/configurar-ssh-push.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# Script para configurar SSH y hacer push a producción +# Uso: ./scripts/configurar-ssh-push.sh + +set -e + +echo "🔐 Configuración de SSH para Push a Producción" +echo "================================================" +echo "" + +# Verificar si ya existe una clave SSH +if [ -f ~/.ssh/id_ed25519 ] || [ -f ~/.ssh/id_rsa ]; then + echo "✅ Ya existe una clave SSH" + if [ -f ~/.ssh/id_ed25519 ]; then + KEY_FILE=~/.ssh/id_ed25519.pub + else + KEY_FILE=~/.ssh/id_rsa.pub + fi + echo "📋 Clave pública: $KEY_FILE" + echo "" + echo "¿Quieres copiar esta clave al servidor? (s/n)" + read -r response + if [[ "$response" =~ ^[Ss]$ ]]; then + echo "Copiando clave al servidor..." + ssh-copy-id -i "$KEY_FILE" root@207.180.226.141 || { + echo "⚠️ No se pudo copiar automáticamente. Copia manualmente:" + echo "" + echo "cat $KEY_FILE | ssh root@207.180.226.141 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'" + echo "" + } + fi +else + echo "📝 No hay clave SSH. Generando nueva clave..." + echo "" + echo "¿Generar nueva clave SSH? (s/n)" + read -r response + if [[ "$response" =~ ^[Ss]$ ]]; then + ssh-keygen -t ed25519 -C "guia-tes-$(date +%Y%m%d)" -f ~/.ssh/id_ed25519 + echo "" + echo "✅ Clave generada. Copiando al servidor..." + ssh-copy-id -i ~/.ssh/id_ed25519.pub root@207.180.226.141 || { + echo "⚠️ No se pudo copiar automáticamente. Copia manualmente:" + echo "" + echo "cat ~/.ssh/id_ed25519.pub | ssh root@207.180.226.141 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'" + echo "" + } + fi +fi + +echo "" +echo "🧪 Probando conexión SSH..." +if ssh -o BatchMode=yes -o ConnectTimeout=5 root@207.180.226.141 "echo 'Conexión exitosa'" 2>/dev/null; then + echo "✅ Conexión SSH exitosa" + echo "" + echo "🚀 Haciendo push a producción..." + cd "$(dirname "$0")/.." + git push production main + echo "" + echo "✅ Push completado exitosamente" +else + echo "❌ La conexión SSH aún no está configurada" + echo "" + echo "Opciones:" + echo "1. Copiar manualmente tu clave pública al servidor" + echo "2. Usar autenticación por contraseña (menos seguro)" + echo "" + echo "Para opción 1, ejecuta:" + echo " cat ~/.ssh/id_ed25519.pub | ssh root@207.180.226.141 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'" + echo "" + echo "Para opción 2, ejecuta:" + echo " GIT_SSH_COMMAND='ssh -o PreferredAuthentications=password' git push production main" +fi + diff --git a/scripts/copiar-clave-ssh.sh b/scripts/copiar-clave-ssh.sh new file mode 100755 index 00000000..81a02df4 --- /dev/null +++ b/scripts/copiar-clave-ssh.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Script para copiar clave SSH al servidor +# Uso: ./scripts/copiar-clave-ssh.sh + +PASSWORD="941259018a" +SERVER="root@207.180.226.141" + +echo "🔐 Copiando clave SSH al servidor..." + +# Método usando ssh con redirección +cat ~/.ssh/id_ed25519.pub | \ +sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no \ + "$SERVER" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys && echo '✅ Clave copiada exitosamente'" + +if [ $? -eq 0 ]; then + echo "✅ Clave SSH copiada correctamente" + echo "" + echo "🧪 Probando conexión..." + sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no "$SERVER" "echo '✅ Conexión SSH exitosa'" + + if [ $? -eq 0 ]; then + echo "" + echo "🚀 Haciendo push a producción..." + cd "$(dirname "$0")/.." + git push production main + fi +else + echo "❌ Error al copiar la clave" + echo "" + echo "Instala sshpass manualmente:" + echo " sudo apt-get install sshpass" + echo "" + echo "O copia la clave manualmente:" + echo " cat ~/.ssh/id_ed25519.pub | ssh root@207.180.226.141 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'" +fi + diff --git a/scripts/deploy/corregir-git-pull-servidor.sh b/scripts/deploy/corregir-git-pull-servidor.sh new file mode 100755 index 00000000..16cb4672 --- /dev/null +++ b/scripts/deploy/corregir-git-pull-servidor.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Script para corregir git pull en el servidor + +SERVER="root@207.180.226.141" +APP_DIR="/var/www/emerges-tes" + +echo "╔══════════════════════════════════════════════════════════════╗" +echo "║ 🔧 CORRIGIENDO GIT PULL EN SERVIDOR ║" +echo "╚══════════════════════════════════════════════════════════════╝" +echo "" + +echo "📤 Configurando git pull en el servidor..." +ssh "$SERVER" << 'EOF' +cd /var/www/emerges-tes + +# Configurar pull para usar merge +git config pull.rebase false + +# Verificar estado +echo "" +echo "✅ Configuración aplicada:" +git config pull.rebase + +# Hacer pull con merge +echo "" +echo "📥 Haciendo pull..." +git pull origin main + +echo "" +echo "✅ Git pull completado" +EOF + +echo "" +echo "✅ Configuración completada" + diff --git a/scripts/deploy/resolver-conflicto-merge.sh b/scripts/deploy/resolver-conflicto-merge.sh new file mode 100755 index 00000000..e1403a42 --- /dev/null +++ b/scripts/deploy/resolver-conflicto-merge.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# Script para resolver conflicto de merge en el servidor + +SERVER="root@207.180.226.141" + +echo "╔══════════════════════════════════════════════════════════════╗" +echo "║ 🔧 RESOLVIENDO CONFLICTO DE MERGE EN SERVIDOR ║" +echo "╚══════════════════════════════════════════════════════════════╝" +echo "" + +ssh "$SERVER" << 'EOF' +cd /var/www/emerges-tes + +echo "📋 Resolviendo conflicto en README.md..." +echo " (Aceptando versión del remoto)" + +# Aceptar versión del remoto (más reciente) +git checkout --theirs README.md +git add README.md + +echo "✅ Conflicto resuelto" +echo "" +echo "📝 Haciendo commit del merge..." +git commit -m "merge: resolver conflicto en README.md (aceptar versión remota)" || { + echo "⚠️ El commit puede que ya esté hecho" +} + +echo "" +echo "✅ Merge completado" +echo "" +echo "📊 Estado actual:" +git status --short +EOF + +echo "" +echo "✅ Conflicto resuelto en el servidor" + diff --git a/scripts/push-produccion.sh b/scripts/push-produccion.sh new file mode 100755 index 00000000..57287d4b --- /dev/null +++ b/scripts/push-produccion.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Script para configurar SSH y hacer push a producción +# Ejecuta este script en tu terminal: ./scripts/push-produccion.sh + +set -e + +PASSWORD="941259018a" +SERVER="root@207.180.226.141" + +echo "╔══════════════════════════════════════════════════════════════╗" +echo "║ CONFIGURACIÓN SSH Y PUSH A PRODUCCIÓN ║" +echo "╚══════════════════════════════════════════════════════════════╝" +echo "" + +# Verificar si sshpass está instalado +if ! command -v sshpass &> /dev/null; then + echo "📦 Instalando sshpass..." + sudo apt-get update -qq + sudo apt-get install -y sshpass +fi + +echo "🔐 Copiando clave SSH al servidor..." +cat ~/.ssh/id_ed25519.pub | \ +sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no \ + "$SERVER" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" + +echo "✅ Clave SSH copiada" +echo "" + +echo "🧪 Probando conexión SSH..." +sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no "$SERVER" "echo '✅ Conexión exitosa'" + +echo "" +echo "🚀 Haciendo push a producción..." +cd "$(dirname "$0")/.." +git push production main + +echo "" +echo "✅ ¡Push completado exitosamente!" + diff --git a/scripts/verify-build.js b/scripts/verify-build.js new file mode 100755 index 00000000..ed512243 --- /dev/null +++ b/scripts/verify-build.js @@ -0,0 +1,93 @@ +#!/usr/bin/env node +/** + * Script de verificación post-build + * Verifica que el build no contiene vendor-other y que todos los chunks están correctamente generados + */ + +const fs = require('fs'); +const path = require('path'); + +const DIST_DIR = path.join(__dirname, '..', 'dist'); +const ASSETS_DIR = path.join(DIST_DIR, 'assets'); + +console.log('🔍 Verificando build...\n'); + +// Verificar que dist existe +if (!fs.existsSync(DIST_DIR)) { + console.error('❌ ERROR: Directorio dist/ no existe'); + process.exit(1); +} + +// Verificar que assets existe +if (!fs.existsSync(ASSETS_DIR)) { + console.error('❌ ERROR: Directorio dist/assets/ no existe'); + process.exit(1); +} + +// Listar todos los archivos en assets +const files = fs.readdirSync(ASSETS_DIR); +const vendorFiles = files.filter(f => f.startsWith('vendor-')); + +console.log('📦 Chunks vendor encontrados:'); +vendorFiles.forEach(file => { + const size = fs.statSync(path.join(ASSETS_DIR, file)).size; + const sizeKB = (size / 1024).toFixed(2); + console.log(` ${file} (${sizeKB} KB)`); +}); + +// CRÍTICO: Verificar que NO existe vendor-other +const vendorOtherFiles = vendorFiles.filter(f => f.includes('vendor-other')); +if (vendorOtherFiles.length > 0) { + console.error('\n❌ ERROR CRÍTICO: Se encontraron archivos vendor-other:'); + vendorOtherFiles.forEach(file => { + console.error(` ${file}`); + }); + console.error('\n🔧 SOLUCIÓN:'); + console.error(' El build está generando vendor-other, lo cual causa errores useLayoutEffect.'); + console.error(' Revisa vite.config.ts y asegúrate de que TODAS las dependencias están clasificadas.'); + process.exit(1); +} + +// Verificar que existen los chunks esperados +const expectedChunks = ['vendor-react', 'vendor-utils', 'vendor-markdown']; +const foundChunks = expectedChunks.filter(chunk => + vendorFiles.some(file => file.includes(chunk)) +); + +console.log('\n✅ Chunks esperados encontrados:'); +foundChunks.forEach(chunk => { + const matchingFiles = vendorFiles.filter(f => f.includes(chunk)); + matchingFiles.forEach(file => { + const size = fs.statSync(path.join(ASSETS_DIR, file)).size; + const sizeKB = (size / 1024).toFixed(2); + console.log(` ✓ ${file} (${sizeKB} KB)`); + }); +}); + +if (foundChunks.length < expectedChunks.length) { + const missing = expectedChunks.filter(c => !foundChunks.includes(c)); + console.warn(`\n⚠️ ADVERTENCIA: Faltan chunks esperados: ${missing.join(', ')}`); +} + +// Verificar index.html +const indexHtml = path.join(DIST_DIR, 'index.html'); +if (!fs.existsSync(indexHtml)) { + console.error('\n❌ ERROR: index.html no existe en dist/'); + process.exit(1); +} + +// Verificar que index.html no referencia vendor-other +const indexContent = fs.readFileSync(indexHtml, 'utf-8'); +if (indexContent.includes('vendor-other')) { + console.error('\n❌ ERROR: index.html referencia vendor-other'); + process.exit(1); +} + +console.log('\n✅ Verificación completada exitosamente'); +console.log(' • No se encontró vendor-other'); +console.log(' • Chunks vendor correctamente generados'); +console.log(' • index.html válido'); +console.log('\n🎉 Build listo para producción\n'); + +process.exit(0); + diff --git a/vite.config.ts b/vite.config.ts index 693d8053..09a5d99d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -56,6 +56,7 @@ export default defineConfig({ if (id.includes('node_modules')) { // SOLUCIÓN DRÁSTICA: Poner TODO lo relacionado con React en un solo chunk // Esto garantiza que React esté disponible antes de cualquier otro código + // IMPORTANTE: Añadir TODAS las dependencias que usan React aquí if ( id.includes('react') || id.includes('react-dom') || @@ -75,7 +76,12 @@ export default defineConfig({ id.includes('input-otp') || id.includes('cmdk') || id.includes('vaul') || - id.includes('react-markdown') + id.includes('react-markdown') || + id.includes('@floating-ui') || + id.includes('@remix-run/router') || + id.includes('use-callback-ref') || + id.includes('use-sidecar') || + id.includes('aria-hidden') ) { return 'vendor-react'; } @@ -84,13 +90,67 @@ export default defineConfig({ return 'vendor-markdown'; } // Utilidades que NO usan React - if (id.includes('zod') || id.includes('date-fns') || id.includes('clsx') || id.includes('tailwind-merge') || id.includes('class-variance-authority')) { + if ( + id.includes('zod') || + id.includes('date-fns') || + id.includes('clsx') || + id.includes('tailwind-merge') || + id.includes('class-variance-authority') || + id.includes('highlight.js') || + id.includes('hast-util') || + id.includes('unist-util') || + id.includes('vfile') || + id.includes('parse5') || + id.includes('entities') || + id.includes('property-information') || + id.includes('style-to-js') || + id.includes('style-to-object') || + id.includes('trough') || + id.includes('bail') || + id.includes('extend') || + id.includes('is-plain-obj') || + id.includes('zwitch') || + id.includes('web-namespaces') || + id.includes('html-void-elements') || + id.includes('html-url-attributes') || + id.includes('comma-separated-tokens') || + id.includes('space-separated-tokens') || + id.includes('estree-util') || + id.includes('decode-named-character-reference') || + id.includes('ccount') || + id.includes('markdown-table') || + id.includes('format') || + id.includes('hastscript') || + id.includes('vfile-location') || + id.includes('vfile-message') || + id.includes('unist-util-stringify-position') || + id.includes('unist-util-is') || + id.includes('unist-util-find-after') || + id.includes('unist-util-visit-parents') || + id.includes('trim-lines') || + id.includes('longest-streak') || + id.includes('hast-util-parse-selector') || + id.includes('detect-node-es') || + id.includes('get-nonce') || + id.includes('@ungap/structured-clone') || + id.includes('devlop') || + id.includes('fault') || + id.includes('hast-util-from-parse5') || + id.includes('hast-util-to-parse5') || + id.includes('inline-style-parser') || + id.includes('tslib') + ) { return 'vendor-utils'; } // CRÍTICO: Si llegamos aquí, algo se nos escapó // Por seguridad, mover TODO a vendor-utils en lugar de vendor-other // Esto previene que cualquier código desconocido use React antes de tiempo - console.warn('[Vite] Unclassified dependency:', id); + // En producción, esto NO debería ocurrir - todos los módulos deberían estar clasificados + if (process.env.NODE_ENV === 'production') { + console.error('[Vite] ERROR: Unclassified dependency in production:', id); + } else { + console.warn('[Vite] Unclassified dependency:', id); + } return 'vendor-utils'; }