1058 lines
30 KiB
Markdown
1058 lines
30 KiB
Markdown
# 🧠 AUDITORÍA ESTRUCTURAL COMPLETA - ESTADO ACTUAL
|
|
|
|
**Proyecto:** Guía TES - Aplicación PWA
|
|
**Fecha:** 2025-01-07
|
|
**Tipo:** Auditoría técnica sin modificaciones
|
|
**Estado:** ✅ COMPLETADO
|
|
|
|
---
|
|
|
|
## 📋 OBJETIVO
|
|
|
|
Documentar el estado real y actual de la aplicación para establecer una base sólida para futuras implementaciones (panel admin, base de datos, SCORM, contenido externo) **SIN ROMPER NADA**.
|
|
|
|
---
|
|
|
|
## 🧩 SECCIÓN A — ESTRUCTURA DEL PROYECTO
|
|
|
|
### Estructura de Carpetas Principal
|
|
|
|
```
|
|
guia-tes/
|
|
├── src/ → Código fuente principal
|
|
│ ├── components/ → Componentes UI reutilizables
|
|
│ │ ├── ui/ → Componentes base (shadcn/ui)
|
|
│ │ ├── guide/ → Componentes específicos de guías
|
|
│ │ └── ... → Otros componentes
|
|
│ ├── data/ → ⚠️ DATOS HARDCODEADOS (crítico)
|
|
│ │ ├── procedures.ts → Protocolos operativos
|
|
│ │ ├── drugs.ts → Vademécum (6 fármacos)
|
|
│ │ ├── guides-index.ts → Índice de guías formativas
|
|
│ │ ├── protocol-guide-manual-mapping.ts → Relaciones bidireccionales
|
|
│ │ └── manual-index.ts → Índice del manual de referencia
|
|
│ ├── pages/ → Páginas/rutas principales
|
|
│ │ ├── Home.tsx → Página inicial
|
|
│ │ ├── RCP.tsx → Protocolo RCP
|
|
│ │ ├── ViaAerea.tsx → Protocolo Vía Aérea
|
|
│ │ ├── Shock.tsx → Protocolo Shock
|
|
│ │ ├── Farmacos.tsx → Vademécum
|
|
│ │ ├── GuiaRefuerzo.tsx → Lista de guías formativas
|
|
│ │ └── ... → Otras páginas
|
|
│ ├── views/ → Vistas especializadas
|
|
│ │ ├── formativo/ → Vistas de contenido formativo
|
|
│ │ │ └── GuideViewer.tsx → Visualizador de guías
|
|
│ │ └── ... → Otras vistas
|
|
│ ├── services/ → Servicios y lógica de negocio
|
|
│ │ ├── content-adapter.ts → ✅ ADAPTER PATTERN (nuevo)
|
|
│ │ ├── content-relations.ts → Servicio de relaciones bidireccionales
|
|
│ │ └── ... → Otros servicios
|
|
│ ├── hooks/ → React hooks personalizados
|
|
│ │ └── ... → Hooks compartidos
|
|
│ ├── utils/ → Utilidades
|
|
│ │ ├── indexeddb.ts → ✅ IndexedDB para cache (nuevo)
|
|
│ │ └── ... → Otras utilidades
|
|
│ ├── App.tsx → Componente raíz y rutas
|
|
│ └── main.tsx → Punto de entrada
|
|
├── public/ → Archivos estáticos
|
|
│ ├── manual/ → Manual de referencia (94 archivos .md)
|
|
│ └── assets/ → Imágenes, iconos, etc.
|
|
├── backend/ → ⚠️ BACKEND NUEVO (separado)
|
|
│ ├── src/ → Código del servidor
|
|
│ ├── database/ → Migraciones SQL
|
|
│ └── scripts/ → Scripts de utilidad
|
|
├── admin-panel/ → ⚠️ PANEL ADMIN NUEVO (separado)
|
|
│ └── src/ → Código del panel React
|
|
└── docs/ → Documentación
|
|
```
|
|
|
|
### Análisis de Carpetas
|
|
|
|
#### ✅ Carpetas Activas y Críticas
|
|
|
|
- **`src/data/`** - ⚠️ **CRÍTICO**: Contiene TODO el contenido hardcodeado
|
|
- `procedures.ts` - Protocolos operativos (usado directamente en múltiples páginas)
|
|
- `drugs.ts` - Vademécum (usado en `Farmacos.tsx`)
|
|
- `guides-index.ts` - Guías formativas (usado en `GuiaRefuerzo.tsx`)
|
|
- **NO TOCAR** sin migración previa
|
|
|
|
- **`src/pages/`** - Páginas principales de la app
|
|
- Cada página importa directamente desde `src/data/`
|
|
- **Acoplamiento fuerte** con datos hardcodeados
|
|
|
|
- **`src/services/content-adapter.ts`** - ✅ **NUEVO**: Patrón Adapter implementado
|
|
- `LocalContentAdapter` - Lee de `src/data/` (fallback)
|
|
- `ExternalContentAdapter` - Lee de Content Pack JSON
|
|
- `ContentAdapterFactory` - Decide qué usar
|
|
- **Extensible** y **no intrusivo**
|
|
|
|
- **`src/utils/indexeddb.ts`** - ✅ **NUEVO**: Cache offline
|
|
- Almacena Content Pack para acceso offline
|
|
- Fallback a localStorage
|
|
|
|
#### ⚠️ Carpetas con Dependencias Externas
|
|
|
|
- **`backend/`** - Backend separado (Express.js + PostgreSQL)
|
|
- **No afecta** la app actual si falla
|
|
- Arquitectura aditiva
|
|
|
|
- **`admin-panel/`** - Panel de administración separado
|
|
- **No afecta** la app actual
|
|
- Arquitectura aditiva
|
|
|
|
#### 📦 Carpetas de Contenido
|
|
|
|
- **`public/manual/`** - 94 archivos Markdown del manual de referencia
|
|
- Cargados dinámicamente
|
|
- **No hardcodeados** en TypeScript
|
|
|
|
---
|
|
|
|
## 🧱 SECCIÓN B — CAPAS FUNCIONALES REALES
|
|
|
|
### Estado Actual de las Capas
|
|
|
|
#### ✅ **Capa Operativa** (EXISTE, pero mezclada)
|
|
|
|
**Ubicación:**
|
|
- `src/data/procedures.ts` - Datos de protocolos
|
|
- `src/pages/RCP.tsx`, `ViaAerea.tsx`, `Shock.tsx` - Visualización
|
|
- Componentes específicos en `src/components/`
|
|
|
|
**Características:**
|
|
- ✅ Datos estructurados (TypeScript interfaces)
|
|
- ✅ Componentes dedicados por protocolo
|
|
- ⚠️ **Hardcodeado** en `src/data/procedures.ts`
|
|
- ⚠️ **Acoplamiento directo** entre páginas y datos
|
|
|
|
**Ejemplo de uso:**
|
|
```typescript
|
|
// src/pages/RCP.tsx
|
|
import { getProcedureById } from '@/data/procedures';
|
|
const protocol = getProcedureById('rcp-adulto-svb');
|
|
```
|
|
|
|
#### ✅ **Capa Formativa** (EXISTE, parcialmente implementada)
|
|
|
|
**Ubicación:**
|
|
- `src/data/guides-index.ts` - Índice de guías
|
|
- `src/pages/GuiaRefuerzo.tsx` - Lista de guías
|
|
- `src/views/formativo/GuideViewer.tsx` - Visualizador
|
|
- `src/components/guide/` - Componentes específicos
|
|
|
|
**Características:**
|
|
- ✅ Estructura definida
|
|
- ✅ Visualizador completo con navegación
|
|
- ⚠️ **Contenido en Markdown** (archivos .md)
|
|
- ⚠️ **No integrado** con sistema de Content Pack aún
|
|
|
|
**Ejemplo de uso:**
|
|
```typescript
|
|
// src/pages/GuiaRefuerzo.tsx
|
|
import { guides } from '@/data/guides-index';
|
|
```
|
|
|
|
#### ✅ **Capa de Referencia** (EXISTE, múltiples fuentes)
|
|
|
|
**Ubicación:**
|
|
- `src/data/drugs.ts` - Vademécum (6 fármacos hardcodeados)
|
|
- `public/manual/` - Manual completo (94 archivos .md)
|
|
- `src/pages/Farmacos.tsx` - Visualización del vademécum
|
|
|
|
**Características:**
|
|
- ✅ Vademécum estructurado (TypeScript)
|
|
- ✅ Manual en Markdown (cargado dinámicamente)
|
|
- ⚠️ **Dos fuentes diferentes** (TypeScript + Markdown)
|
|
- ⚠️ **Vademécum limitado** (solo 6 fármacos)
|
|
|
|
**Ejemplo de uso:**
|
|
```typescript
|
|
// src/pages/Farmacos.tsx
|
|
import { drugs } from '@/data/drugs';
|
|
```
|
|
|
|
### ¿Están Mezcladas las Capas?
|
|
|
|
**Respuesta:** ⚠️ **PARCIALMENTE**
|
|
|
|
- ✅ **Separación conceptual** existe (operativa, formativa, referencia)
|
|
- ⚠️ **Implementación mezclada**:
|
|
- Operativa: TypeScript hardcodeado
|
|
- Formativa: Markdown + TypeScript
|
|
- Referencia: TypeScript (vademécum) + Markdown (manual)
|
|
- ✅ **Nueva arquitectura** (`ContentAdapter`) permite separación futura
|
|
|
|
### Archivos Concretos por Capa
|
|
|
|
| Capa | Archivos de Datos | Archivos de Visualización |
|
|
|------|------------------|---------------------------|
|
|
| **Operativa** | `src/data/procedures.ts` | `src/pages/RCP.tsx`, `ViaAerea.tsx`, `Shock.tsx` |
|
|
| **Formativa** | `src/data/guides-index.ts` | `src/pages/GuiaRefuerzo.tsx`, `src/views/formativo/GuideViewer.tsx` |
|
|
| **Referencia** | `src/data/drugs.ts` + `public/manual/` | `src/pages/Farmacos.tsx` + visualizador de manual |
|
|
|
|
---
|
|
|
|
## 📦 SECCIÓN C — MODELO DE DATOS ACTUAL (REAL)
|
|
|
|
### 1. Procedures (Protocolos Operativos)
|
|
|
|
**Archivo:** `src/data/procedures.ts`
|
|
|
|
**Estructura:**
|
|
```typescript
|
|
interface Procedure {
|
|
id: string; // Identificador único (slug)
|
|
title: string; // Título completo
|
|
shortTitle: string; // Título corto para UI
|
|
category: string; // Categoría (ej: "soporte_vital")
|
|
subcategory?: string; // Subcategoría opcional
|
|
priority: 'critica' | 'alta' | 'media' | 'baja';
|
|
ageGroup: 'adulto' | 'pediatrico' | 'todos';
|
|
steps: string[]; // Pasos del protocolo
|
|
warnings?: string[]; // Advertencias críticas
|
|
keyPoints?: string[]; // Puntos clave
|
|
equipment?: string[]; // Equipamiento necesario
|
|
drugs?: string[]; // Fármacos relacionados (por nombre)
|
|
}
|
|
```
|
|
|
|
**Características:**
|
|
- ✅ Tipado fuerte (TypeScript)
|
|
- ✅ Estructura clara y consistente
|
|
- ⚠️ **Hardcodeado** en archivo TypeScript
|
|
- ⚠️ **Relaciones implícitas** con fármacos (solo nombres)
|
|
- ⚠️ **Sin versionado**
|
|
- ⚠️ **Sin metadatos** de auditoría
|
|
|
|
**Funciones de acceso:**
|
|
```typescript
|
|
export function getProcedureById(id: string): Procedure | undefined
|
|
export function getAllProcedures(): Procedure[]
|
|
```
|
|
|
|
**Limitaciones:**
|
|
- No permite relaciones explícitas con otros contenidos
|
|
- No tiene estado (draft/published)
|
|
- No tiene versionado
|
|
- No tiene metadatos de creación/modificación
|
|
|
|
### 2. Drugs (Vademécum)
|
|
|
|
**Archivo:** `src/data/drugs.ts`
|
|
|
|
**Estructura:**
|
|
```typescript
|
|
interface Drug {
|
|
id: string; // Identificador único (slug)
|
|
genericName: string; // Nombre genérico
|
|
tradeName: string; // Nombre comercial
|
|
category: string; // Categoría farmacológica
|
|
presentation: string; // Presentación
|
|
adultDose: string; // Dosis adulto
|
|
pediatricDose?: string; // Dosis pediátrica (opcional)
|
|
routes: string[]; // Vías de administración
|
|
dilution?: string; // Dilución
|
|
indications: string[]; // Indicaciones
|
|
contraindications: string[]; // Contraindicaciones
|
|
sideEffects?: string; // Efectos adversos
|
|
antidote?: string; // Antídoto
|
|
notes?: string[]; // Notas
|
|
criticalPoints?: string[]; // Puntos críticos TES
|
|
source?: string; // Fuente
|
|
}
|
|
```
|
|
|
|
**Características:**
|
|
- ✅ Tipado fuerte
|
|
- ✅ Estructura completa
|
|
- ⚠️ **Solo 6 fármacos** hardcodeados
|
|
- ⚠️ **Sin relaciones** con protocolos
|
|
- ⚠️ **Sin versionado**
|
|
|
|
**Funciones de acceso:**
|
|
```typescript
|
|
export function getDrugById(id: string): Drug | undefined
|
|
export function findDrugByName(name: string): Drug | undefined
|
|
export const drugs: Drug[] = [...]
|
|
```
|
|
|
|
**Limitaciones:**
|
|
- Muy limitado (solo 6 fármacos)
|
|
- No tiene estado
|
|
- No tiene versionado
|
|
- No tiene metadatos
|
|
|
|
### 3. Guides (Guías Formativas)
|
|
|
|
**Archivo:** `src/data/guides-index.ts`
|
|
|
|
**Estructura:**
|
|
```typescript
|
|
interface Guide {
|
|
id: string; // Identificador único
|
|
titulo: string; // Título
|
|
descripcion: string; // Descripción
|
|
icono: string; // Icono (lucide-react)
|
|
secciones?: GuideSection[]; // Secciones (Markdown)
|
|
}
|
|
```
|
|
|
|
**Características:**
|
|
- ✅ Estructura definida
|
|
- ⚠️ **Contenido en Markdown** (archivos externos)
|
|
- ⚠️ **Carga dinámica** de contenido
|
|
- ✅ **10 guías** definidas
|
|
|
|
**Funciones de acceso:**
|
|
```typescript
|
|
export const guides: Guide[] = [...]
|
|
// Carga dinámica de contenido Markdown
|
|
```
|
|
|
|
**Limitaciones:**
|
|
- Contenido separado (índice en TS, contenido en MD)
|
|
- No tiene versionado
|
|
- No tiene metadatos
|
|
|
|
### 4. Checklists
|
|
|
|
**Estado:** ⚠️ **NO EXISTE como estructura independiente**
|
|
|
|
**Ubicación actual:**
|
|
- Checklists están **embebidos** en componentes de protocolos
|
|
- Ejemplo: `src/pages/RCP.tsx` tiene `rcpChecklistSteps` hardcodeado
|
|
|
|
**Estructura implícita:**
|
|
```typescript
|
|
// Dentro de componentes
|
|
const checklistSteps = [
|
|
{ id: '1', text: '...', checked: false },
|
|
...
|
|
]
|
|
```
|
|
|
|
**Limitaciones:**
|
|
- No es reutilizable
|
|
- No tiene estructura de datos propia
|
|
- Duplicado en múltiples componentes
|
|
|
|
### 5. Manual de Referencia
|
|
|
|
**Ubicación:** `public/manual/` (94 archivos .md)
|
|
|
|
**Estructura:**
|
|
- Organizado en bloques (BLOQUE_0 a BLOQUE_15)
|
|
- Cargado dinámicamente
|
|
- **No hardcodeado** en TypeScript
|
|
|
|
**Características:**
|
|
- ✅ Separado del código
|
|
- ✅ Fácil de modificar
|
|
- ⚠️ **Sin estructura de datos** en TypeScript
|
|
- ⚠️ **Sin relaciones** explícitas
|
|
|
|
### 6. Relaciones Bidireccionales
|
|
|
|
**Archivo:** `src/data/protocol-guide-manual-mapping.ts`
|
|
|
|
**Estructura:**
|
|
```typescript
|
|
interface ProtocolGuideManualMapping {
|
|
protocoloId: string;
|
|
protocoloRuta: string;
|
|
tieneGuia: boolean;
|
|
guiaId?: string;
|
|
guiaRuta?: string;
|
|
tieneManual: boolean;
|
|
manualBloque?: string;
|
|
manualTitulo?: string;
|
|
manualRuta?: string;
|
|
}
|
|
```
|
|
|
|
**Características:**
|
|
- ✅ **NUEVO**: Sistema de relaciones implementado
|
|
- ✅ Permite enlaces bidireccionales
|
|
- ⚠️ **Hardcodeado** en TypeScript
|
|
- ✅ Usado por `src/services/content-relations.ts`
|
|
|
|
---
|
|
|
|
## 🔗 SECCIÓN D — RELACIONES ENTRE DATOS
|
|
|
|
### Relaciones Actuales
|
|
|
|
#### ✅ Protocolo → Guía Formativa
|
|
|
|
**Estado:** ✅ **IMPLEMENTADO**
|
|
|
|
**Cómo funciona:**
|
|
- Mapeo en `protocol-guide-manual-mapping.ts`
|
|
- Servicio `content-relations.ts` expone `getProtocolRelations()`
|
|
- Componentes muestran enlaces en UI
|
|
|
|
**Ejemplo:**
|
|
```typescript
|
|
// src/pages/RCP.tsx
|
|
const relations = getProtocolRelations('rcp-adulto-svb');
|
|
if (relations.guide) {
|
|
// Mostrar enlace a guía formativa
|
|
}
|
|
```
|
|
|
|
#### ✅ Protocolo → Manual de Referencia
|
|
|
|
**Estado:** ✅ **IMPLEMENTADO**
|
|
|
|
**Cómo funciona:**
|
|
- Mismo sistema de mapeo
|
|
- Enlaces a bloques del manual
|
|
|
|
#### ✅ Guía → Protocolo
|
|
|
|
**Estado:** ✅ **IMPLEMENTADO**
|
|
|
|
**Cómo funciona:**
|
|
- Mapeo bidireccional
|
|
- `getGuideRelations()` en `content-relations.ts`
|
|
|
|
#### ⚠️ Fármaco → Protocolo
|
|
|
|
**Estado:** ⚠️ **IMPLÍCITO (solo por nombre)**
|
|
|
|
**Cómo funciona:**
|
|
- Protocolos tienen array `drugs?: string[]` con nombres
|
|
- Búsqueda por nombre: `findDrugByName()`
|
|
- **No hay relación explícita** en base de datos
|
|
|
|
**Limitación:**
|
|
- Si cambia el nombre del fármaco, se rompe la relación
|
|
- No hay validación de que el fármaco exista
|
|
|
|
#### ❌ Fármaco → Guía
|
|
|
|
**Estado:** ❌ **NO EXISTE**
|
|
|
|
#### ❌ Checklist → Protocolo
|
|
|
|
**Estado:** ❌ **NO EXISTE** (checklists embebidos)
|
|
|
|
### Resumen de Relaciones
|
|
|
|
| Desde | Hacia | Estado | Tipo |
|
|
|-------|-------|--------|------|
|
|
| Protocolo | Guía | ✅ Implementado | Explícito (mapping) |
|
|
| Protocolo | Manual | ✅ Implementado | Explícito (mapping) |
|
|
| Guía | Protocolo | ✅ Implementado | Explícito (mapping) |
|
|
| Protocolo | Fármaco | ⚠️ Implícito | Por nombre (string) |
|
|
| Fármaco | Protocolo | ❌ No existe | - |
|
|
| Checklist | Protocolo | ❌ No existe | Embebido |
|
|
|
|
---
|
|
|
|
## 🧠 SECCIÓN E — FLUJO DE USO DE LA APP
|
|
|
|
### Flujo Real del Usuario
|
|
|
|
#### 1. **Pantalla Inicial** (`Home.tsx`)
|
|
|
|
**Qué se carga:**
|
|
- Lista de protocolos principales
|
|
- Accesos rápidos
|
|
- Búsqueda global
|
|
|
|
**Datos cargados:**
|
|
```typescript
|
|
// Carga directa desde src/data/
|
|
import { getAllProcedures } from '@/data/procedures';
|
|
```
|
|
|
|
**Decisión de qué mostrar:**
|
|
- Hardcodeado en componente
|
|
- Prioridad por `priority` del protocolo
|
|
|
|
#### 2. **Navegación**
|
|
|
|
**Componentes:**
|
|
- `Header` - Navegación superior
|
|
- `BottomNav` - Navegación inferior (móvil)
|
|
- `MenuSheet` - Menú lateral
|
|
|
|
**Rutas principales:**
|
|
```typescript
|
|
// src/App.tsx
|
|
<Route path="/" element={<Home />} />
|
|
<Route path="/rcp" element={<RCP />} />
|
|
<Route path="/via-aerea" element={<ViaAerea />} />
|
|
<Route path="/shock" element={<Shock />} />
|
|
<Route path="/farmacos" element={<Farmacos />} />
|
|
<Route path="/guia-refuerzo" element={<GuiaRefuerzo />} />
|
|
<Route path="/guia-refuerzo/:guia" element={<GuideViewer />} />
|
|
```
|
|
|
|
#### 3. **Selección de Contenido**
|
|
|
|
**Protocolos:**
|
|
- Usuario hace clic en protocolo
|
|
- Navega a página específica (`/rcp`, `/via-aerea`, etc.)
|
|
- Componente carga datos con `getProcedureById()`
|
|
|
|
**Guías:**
|
|
- Usuario navega a `/guia-refuerzo`
|
|
- Ve lista de guías
|
|
- Selecciona una guía
|
|
- Carga contenido Markdown dinámicamente
|
|
|
|
**Fármacos:**
|
|
- Usuario navega a `/farmacos`
|
|
- Ve lista de 6 fármacos
|
|
- Puede buscar/filtrar
|
|
|
|
#### 4. **Visualización**
|
|
|
|
**Protocolos:**
|
|
- Componente específico por protocolo
|
|
- Muestra pasos, advertencias, puntos clave
|
|
- Checklist embebido
|
|
- Enlaces a guías/manual (si existen)
|
|
|
|
**Guías:**
|
|
- `GuideViewer` renderiza Markdown
|
|
- Navegación entre secciones
|
|
- Enlaces bidireccionales
|
|
|
|
**Fármacos:**
|
|
- Tabla o cards
|
|
- Información completa del fármaco
|
|
|
|
#### 5. **Acciones Posibles**
|
|
|
|
- ✅ Ver contenido
|
|
- ✅ Navegar entre capas (protocolo → guía → manual)
|
|
- ✅ Búsqueda
|
|
- ✅ Modo checklist (en algunos protocolos)
|
|
- ❌ Editar contenido (no implementado en app)
|
|
- ❌ Favoritos (no implementado)
|
|
- ❌ Historial (no implementado)
|
|
|
|
### ¿Dónde se Decide Qué se Muestra?
|
|
|
|
**Respuesta:** ⚠️ **HARDCODEADO en componentes**
|
|
|
|
- Cada página importa directamente desde `src/data/`
|
|
- Lógica de filtrado/ordenación en componentes
|
|
- **No hay capa de lógica de negocio** separada
|
|
|
|
### ¿Qué Datos se Cargan Primero?
|
|
|
|
**Orden de carga:**
|
|
1. **App.tsx** - Configuración y rutas
|
|
2. **Home.tsx** - Carga `getAllProcedures()`
|
|
3. **Páginas específicas** - Carga datos cuando se navega
|
|
|
|
**Estrategia:**
|
|
- ⚠️ **Carga bajo demanda** (no precarga)
|
|
- ⚠️ **Sin cache** de datos (excepto Content Pack nuevo)
|
|
- ✅ **Service Worker** para assets estáticos
|
|
|
|
### ¿Qué es Crítico para Offline?
|
|
|
|
**Crítico:**
|
|
- ✅ **Service Worker** - Cache de assets
|
|
- ✅ **Content Pack** (nuevo) - Cache en IndexedDB
|
|
- ⚠️ **Datos hardcodeados** - Siempre disponibles (bundle)
|
|
|
|
**No crítico:**
|
|
- ❌ Backend API (no usado en app actual)
|
|
- ❌ Panel admin (separado)
|
|
|
|
---
|
|
|
|
## ⚠️ SECCIÓN F — PUNTOS CRÍTICOS / NO TOCAR
|
|
|
|
### ❌ Archivos NO TOCAR (Sin Migración Previa)
|
|
|
|
#### 1. `src/data/procedures.ts`
|
|
|
|
**Razón:**
|
|
- Usado directamente en múltiples páginas
|
|
- Importado en: `RCP.tsx`, `ViaAerea.tsx`, `Shock.tsx`, `Home.tsx`
|
|
- **Cambios romperían** toda la app
|
|
|
|
**Riesgo:** 🔴 **CRÍTICO**
|
|
|
|
#### 2. `src/data/drugs.ts`
|
|
|
|
**Razón:**
|
|
- Usado en `Farmacos.tsx`
|
|
- Funciones `getDrugById()`, `findDrugByName()` usadas en protocolos
|
|
- **Cambios romperían** vademécum y referencias en protocolos
|
|
|
|
**Riesgo:** 🔴 **CRÍTICO**
|
|
|
|
#### 3. `src/data/guides-index.ts`
|
|
|
|
**Razón:**
|
|
- Usado en `GuiaRefuerzo.tsx`
|
|
- Estructura esperada por `GuideViewer`
|
|
- **Cambios romperían** visualización de guías
|
|
|
|
**Riesgo:** 🔴 **CRÍTICO**
|
|
|
|
#### 4. `src/pages/RCP.tsx`, `ViaAerea.tsx`, `Shock.tsx`
|
|
|
|
**Razón:**
|
|
- Componentes críticos de protocolos
|
|
- Lógica de visualización específica
|
|
- Checklists embebidos
|
|
- **Refactorizar requiere** migración completa
|
|
|
|
**Riesgo:** 🟠 **IMPORTANTE**
|
|
|
|
### ⚠️ Componentes Frágiles
|
|
|
|
#### 1. Checklists Embebidos
|
|
|
|
**Ubicación:** Dentro de componentes de protocolos
|
|
|
|
**Problema:**
|
|
- Lógica duplicada
|
|
- No reutilizable
|
|
- Difícil de mantener
|
|
|
|
**Riesgo:** 🟡 **TOLERABLE** (funciona, pero no escalable)
|
|
|
|
#### 2. Búsqueda de Fármacos por Nombre
|
|
|
|
**Ubicación:** `src/pages/RCP.tsx` y otros
|
|
|
|
**Problema:**
|
|
```typescript
|
|
const findDrugByName = (name: string) => {
|
|
return drugs.find(d =>
|
|
d.genericName.toLowerCase().includes(name.toLowerCase())
|
|
);
|
|
};
|
|
```
|
|
|
|
**Riesgo:** 🟠 **IMPORTANTE** (frágil si cambian nombres)
|
|
|
|
### 🔒 Lógica Duplicada Peligrosa
|
|
|
|
#### 1. Carga de Datos
|
|
|
|
**Problema:**
|
|
- Múltiples páginas importan directamente desde `src/data/`
|
|
- Sin capa de abstracción (excepto nuevo `ContentAdapter`)
|
|
|
|
**Riesgo:** 🟡 **TOLERABLE** (funciona, pero no ideal)
|
|
|
|
#### 2. Relaciones Bidireccionales
|
|
|
|
**Problema:**
|
|
- Mapeo hardcodeado en `protocol-guide-manual-mapping.ts`
|
|
- Si cambia un ID, hay que actualizar manualmente
|
|
|
|
**Riesgo:** 🟠 **IMPORTANTE**
|
|
|
|
---
|
|
|
|
## 🧩 SECCIÓN G — EXTENSIBILIDAD REAL
|
|
|
|
### ✅ Puntos Extensibles (Ya Implementados)
|
|
|
|
#### 1. **ContentAdapter Pattern** ✅
|
|
|
|
**Ubicación:** `src/services/content-adapter.ts`
|
|
|
|
**Características:**
|
|
- ✅ **Abstracción completa** de fuente de datos
|
|
- ✅ **Fallback automático** (External → Local)
|
|
- ✅ **No intrusivo** (no rompe código existente)
|
|
- ✅ **Extensible** (fácil añadir nuevos adapters)
|
|
|
|
**Cómo funciona:**
|
|
```typescript
|
|
// Factory decide qué adapter usar
|
|
const adapter = ContentAdapterFactory.create();
|
|
const protocol = adapter.getProtocol('rcp-adulto-svb');
|
|
```
|
|
|
|
**Ventajas:**
|
|
- Permite inyectar contenido externo
|
|
- Mantiene compatibilidad con datos locales
|
|
- Zero-downtime migration path
|
|
|
|
#### 2. **IndexedDB Cache** ✅
|
|
|
|
**Ubicación:** `src/utils/indexeddb.ts`
|
|
|
|
**Características:**
|
|
- ✅ Cache offline del Content Pack
|
|
- ✅ Fallback a localStorage
|
|
- ✅ Expiración automática
|
|
|
|
**Extensibilidad:**
|
|
- Fácil añadir más tipos de cache
|
|
- Permite estrategias de sincronización
|
|
|
|
#### 3. **Content Relations Service** ✅
|
|
|
|
**Ubicación:** `src/services/content-relations.ts`
|
|
|
|
**Características:**
|
|
- ✅ Abstrae relaciones bidireccionales
|
|
- ✅ Fácil de extender con nuevas relaciones
|
|
|
|
### ⚠️ Puntos Parcialmente Extensibles
|
|
|
|
#### 1. **Estructura de Procedures**
|
|
|
|
**Estado:** ⚠️ **PARCIAL**
|
|
|
|
**Extensible:**
|
|
- ✅ Interface TypeScript permite añadir campos
|
|
- ✅ Componentes pueden manejar campos opcionales
|
|
|
|
**No extensible:**
|
|
- ❌ Fuente de datos (hardcodeado)
|
|
- ❌ Versionado (no existe)
|
|
- ❌ Estados (no existe)
|
|
|
|
#### 2. **Estructura de Drugs**
|
|
|
|
**Estado:** ⚠️ **PARCIAL**
|
|
|
|
**Mismo análisis que Procedures**
|
|
|
|
### ❌ Puntos NO Extensibles (Sin Refactor)
|
|
|
|
#### 1. **Checklists Embebidos**
|
|
|
|
**Problema:**
|
|
- Lógica dentro de componentes
|
|
- No hay estructura de datos
|
|
- No reutilizable
|
|
|
|
**Solución requerida:**
|
|
- Extraer a estructura de datos
|
|
- Crear componente reutilizable
|
|
- Migrar checklists existentes
|
|
|
|
#### 2. **Carga Directa desde `src/data/`**
|
|
|
|
**Problema:**
|
|
- Múltiples imports directos
|
|
- Sin capa de abstracción (excepto nuevo adapter)
|
|
|
|
**Solución requerida:**
|
|
- Migrar a `ContentAdapter`
|
|
- Deprecar imports directos gradualmente
|
|
|
|
#### 3. **Relaciones Implícitas (Fármacos)**
|
|
|
|
**Problema:**
|
|
- Relación por nombre (string)
|
|
- No validada
|
|
- Frágil
|
|
|
|
**Solución requerida:**
|
|
- Sistema de relaciones explícitas
|
|
- Validación de integridad
|
|
|
|
---
|
|
|
|
## 📊 SECCIÓN H — DEUDA TÉCNICA REAL
|
|
|
|
### 🔴 Crítica (Debe Resolverse Pronto)
|
|
|
|
#### 1. **Datos Hardcodeados en TypeScript**
|
|
|
|
**Ubicación:** `src/data/*.ts`
|
|
|
|
**Problema:**
|
|
- Imposible modificar sin deploy
|
|
- No hay versionado
|
|
- No hay estados (draft/published)
|
|
- No hay auditoría
|
|
|
|
**Impacto:**
|
|
- Bloquea gestión externa de contenido
|
|
- Bloquea panel admin
|
|
- Bloquea SCORM
|
|
|
|
**Esfuerzo de resolución:** Alto (migración completa)
|
|
|
|
#### 2. **Acoplamiento Fuerte Páginas → Datos**
|
|
|
|
**Problema:**
|
|
- Páginas importan directamente desde `src/data/`
|
|
- Sin capa de abstracción (excepto nuevo adapter)
|
|
|
|
**Impacto:**
|
|
- Difícil cambiar fuente de datos
|
|
- Bloquea migración gradual
|
|
|
|
**Esfuerzo de resolución:** Medio (migrar a ContentAdapter)
|
|
|
|
#### 3. **Relaciones Implícitas (Fármacos)**
|
|
|
|
**Problema:**
|
|
- Protocolos referencian fármacos por nombre (string)
|
|
- No validado
|
|
- Se rompe si cambia nombre
|
|
|
|
**Impacto:**
|
|
- Errores silenciosos
|
|
- Mantenimiento difícil
|
|
|
|
**Esfuerzo de resolución:** Medio (sistema de relaciones)
|
|
|
|
### 🟠 Importante (Debe Planificarse)
|
|
|
|
#### 1. **Checklists No Estructurados**
|
|
|
|
**Problema:**
|
|
- Embebidos en componentes
|
|
- Duplicados
|
|
- No reutilizables
|
|
|
|
**Impacto:**
|
|
- Mantenimiento difícil
|
|
- Inconsistencias
|
|
|
|
**Esfuerzo de resolución:** Medio (extraer a estructura)
|
|
|
|
#### 2. **Falta de Versionado**
|
|
|
|
**Problema:**
|
|
- No hay historial de cambios
|
|
- No hay rollback
|
|
- No hay trazabilidad
|
|
|
|
**Impacto:**
|
|
- Imposible auditar cambios
|
|
- Riesgo de pérdida de datos
|
|
|
|
**Esfuerzo de resolución:** Alto (sistema completo)
|
|
|
|
#### 3. **Dos Fuentes de Referencia**
|
|
|
|
**Problema:**
|
|
- Vademécum en TypeScript (`drugs.ts`)
|
|
- Manual en Markdown (`public/manual/`)
|
|
|
|
**Impacto:**
|
|
- Inconsistencias posibles
|
|
- Mantenimiento separado
|
|
|
|
**Esfuerzo de resolución:** Medio (unificar)
|
|
|
|
### 🟡 Tolerable (Puede Esperar)
|
|
|
|
#### 1. **Falta de Tipado Fuerte en Algunos Lugares**
|
|
|
|
**Problema:**
|
|
- Algunos `any` o tipos débiles
|
|
- No crítico, pero mejorable
|
|
|
|
**Impacto:** Bajo
|
|
|
|
**Esfuerzo de resolución:** Bajo (mejora incremental)
|
|
|
|
#### 2. **Lógica Duplicada en Componentes**
|
|
|
|
**Problema:**
|
|
- Algunas funciones repetidas
|
|
- No crítico, pero mejorable
|
|
|
|
**Impacto:** Bajo
|
|
|
|
**Esfuerzo de resolución:** Bajo (refactor gradual)
|
|
|
|
#### 3. **Falta de Tests**
|
|
|
|
**Problema:**
|
|
- No hay tests automatizados
|
|
- No crítico para MVP
|
|
|
|
**Impacto:** Bajo (ahora), Alto (futuro)
|
|
|
|
**Esfuerzo de resolución:** Alto (sistema completo)
|
|
|
|
---
|
|
|
|
## 🧭 SECCIÓN I — CONCLUSIÓN EJECUTIVA
|
|
|
|
### ¿La Estructura Actual Aguanta el Sistema Propuesto?
|
|
|
|
**Respuesta:** ✅ **SÍ, CON ARQUITECTURA ADITIVA**
|
|
|
|
**Análisis:**
|
|
|
|
#### ✅ **Puntos Fuertes**
|
|
|
|
1. **ContentAdapter ya implementado** - Permite inyectar contenido externo sin romper nada
|
|
2. **Separación conceptual de capas** - Existe (operativa, formativa, referencia)
|
|
3. **Arquitectura aditiva del backend** - No afecta app actual
|
|
4. **IndexedDB cache** - Ya implementado para offline
|
|
|
|
#### ⚠️ **Limitaciones Actuales**
|
|
|
|
1. **Datos hardcodeados** - Bloquean gestión externa directa
|
|
2. **Acoplamiento páginas → datos** - Requiere migración gradual
|
|
3. **Falta de versionado** - No crítico para MVP, sí para producción
|
|
|
|
#### ✅ **Solución: Migración Gradual**
|
|
|
|
**Estrategia:**
|
|
1. ✅ **ContentAdapter ya implementado** - Permite migración sin romper
|
|
2. ✅ **Backend separado** - No afecta app actual
|
|
3. ⏳ **Migrar páginas gradualmente** - De `src/data/` a `ContentAdapter`
|
|
4. ⏳ **Mantener compatibilidad** - `LocalContentAdapter` como fallback
|
|
|
|
### ¿Qué se Puede Reutilizar?
|
|
|
|
#### ✅ **Totalmente Reutilizable**
|
|
|
|
1. **Estructuras de datos TypeScript** - Interfaces de `Procedure`, `Drug`, `Guide`
|
|
2. **Componentes de visualización** - `RCP.tsx`, `ViaAerea.tsx`, etc.
|
|
3. **Sistema de relaciones** - `content-relations.ts`
|
|
4. **ContentAdapter** - Ya implementado y funcional
|
|
|
|
#### ⚠️ **Reutilizable con Modificaciones**
|
|
|
|
1. **Páginas de protocolos** - Cambiar de `getProcedureById()` a `adapter.getProtocol()`
|
|
2. **Página de fármacos** - Cambiar de `drugs` array a `adapter.getAllDrugs()`
|
|
3. **Página de guías** - Cambiar de `guides` array a `adapter.getAllGuides()`
|
|
|
|
#### ❌ **No Reutilizable (Requiere Refactor)**
|
|
|
|
1. **Checklists embebidos** - Requieren extracción a estructura
|
|
2. **Lógica de búsqueda por nombre** - Requiere sistema de relaciones
|
|
|
|
### ¿Qué Debe Aislarse?
|
|
|
|
#### 🔴 **Crítico Aislar**
|
|
|
|
1. **`src/data/*.ts`** - NO TOCAR directamente
|
|
- Migrar a ContentAdapter
|
|
- Mantener como fallback
|
|
|
|
2. **Componentes de protocolos** - Aislar lógica de datos
|
|
- Usar ContentAdapter
|
|
- No importar directamente desde `src/data/`
|
|
|
|
#### 🟠 **Importante Aislar**
|
|
|
|
1. **Lógica de relaciones** - Ya aislada en `content-relations.ts` ✅
|
|
2. **Cache offline** - Ya aislado en `indexeddb.ts` ✅
|
|
|
|
### ¿Por Dónde Conviene Empezar SIN ROMPER NADA?
|
|
|
|
#### ✅ **Fase 1: Ya Completada** ✅
|
|
|
|
1. ✅ ContentAdapter implementado
|
|
2. ✅ ExternalContentAdapter funcional
|
|
3. ✅ IndexedDB cache implementado
|
|
4. ✅ Content Relations implementado
|
|
5. ✅ Backend separado creado
|
|
6. ✅ Panel admin separado creado
|
|
|
|
#### ⏳ **Fase 2: Migración Gradual (Siguiente)**
|
|
|
|
**Orden recomendado:**
|
|
|
|
1. **Migrar páginas una por una:**
|
|
- Empezar con páginas menos críticas
|
|
- Cambiar de `getProcedureById()` a `useProtocolAdapter()`
|
|
- Probar exhaustivamente
|
|
- Continuar con siguiente página
|
|
|
|
2. **Migrar vademécum:**
|
|
- Cambiar `Farmacos.tsx` a usar `ContentAdapter`
|
|
- Backend ya tiene drugs (35 fármacos)
|
|
- Content Pack ya incluye drugs
|
|
|
|
3. **Migrar guías:**
|
|
- Cambiar `GuiaRefuerzo.tsx` a usar `ContentAdapter`
|
|
- Backend ya tiene guides
|
|
- Content Pack ya incluye guides
|
|
|
|
#### ⏳ **Fase 3: Mejoras (Futuro)**
|
|
|
|
1. **Extraer checklists:**
|
|
- Crear estructura de datos
|
|
- Componente reutilizable
|
|
- Migrar checklists existentes
|
|
|
|
2. **Sistema de relaciones explícitas:**
|
|
- Reemplazar búsqueda por nombre
|
|
- Validación de integridad
|
|
|
|
3. **Versionado:**
|
|
- Implementar en backend (ya existe estructura)
|
|
- UI para ver historial
|
|
|
|
### Recomendaciones Finales
|
|
|
|
#### ✅ **Hacer Ahora**
|
|
|
|
1. **Continuar migración gradual** - Páginas a ContentAdapter
|
|
2. **Probar exhaustivamente** - Cada migración
|
|
3. **Mantener fallback** - LocalContentAdapter siempre disponible
|
|
|
|
#### ⏳ **Planificar**
|
|
|
|
1. **Extraer checklists** - Estructura de datos
|
|
2. **Sistema de relaciones** - Explícitas y validadas
|
|
3. **Versionado completo** - Backend + UI
|
|
|
|
#### ❌ **NO Hacer**
|
|
|
|
1. **Refactor masivo** - Riesgo alto de romper
|
|
2. **Eliminar `src/data/`** - Mantener como fallback
|
|
3. **Cambiar estructuras** - Sin migración previa
|
|
|
|
---
|
|
|
|
## 📋 RESUMEN TÉCNICO
|
|
|
|
### Estado Actual
|
|
|
|
- ✅ **Arquitectura aditiva** implementada (ContentAdapter)
|
|
- ✅ **Backend separado** (no afecta app)
|
|
- ✅ **Panel admin separado** (no afecta app)
|
|
- ⚠️ **Datos hardcodeados** (requieren migración gradual)
|
|
- ⚠️ **Acoplamiento páginas → datos** (mejorable)
|
|
|
|
### Capacidad de Extensión
|
|
|
|
- ✅ **Alta** - ContentAdapter permite inyectar contenido externo
|
|
- ✅ **Alta** - Backend listo para gestión de contenido
|
|
- ✅ **Alta** - Panel admin listo para edición
|
|
- ⚠️ **Media** - Requiere migración gradual de páginas
|
|
|
|
### Riesgo de Ruptura
|
|
|
|
- ✅ **Bajo** - Arquitectura aditiva
|
|
- ✅ **Bajo** - Fallback siempre disponible
|
|
- ⚠️ **Medio** - Si se toca `src/data/` directamente
|
|
- ✅ **Bajo** - Backend/Admin separados
|
|
|
|
### Conclusión
|
|
|
|
**La estructura actual SÍ aguanta el sistema propuesto** mediante:
|
|
|
|
1. ✅ **ContentAdapter** - Ya implementado
|
|
2. ✅ **Migración gradual** - Sin romper nada
|
|
3. ✅ **Fallback** - Siempre disponible
|
|
4. ✅ **Arquitectura aditiva** - Backend/Admin separados
|
|
|
|
**Próximo paso:** Migrar páginas gradualmente a ContentAdapter.
|
|
|
|
---
|
|
|
|
**Última actualización:** 2025-01-07
|
|
**Estado:** ✅ AUDITORÍA COMPLETA
|
|
|