codigo0/docs/ARQUITECTURA_PANEL_ADMIN.md

18 KiB
Raw Blame History

🏗️ ARQUITECTURA DEL PANEL DE ADMINISTRACIÓN - EMERGES TES

Versión: 1.0
Fecha: 2025-01-XX
Estado: Documento de Diseño - Sin Implementación
Autor: Arquitecto de Software Senior + Diseñador Instruccional Sanitario


🎯 PROPÓSITO DEL DOCUMENTO

Este documento define LA ARQUITECTURA CONCEPTUAL del Panel de Administración de Contenidos para EMERGES TES. Es el diseño técnico que:

  • Permite editar contenido SIN tocar código React
  • Mantiene compatibilidad offline-first
  • Garantiza seguridad en entorno sanitario
  • Permite auditoría y versionado
  • Escala a nivel institucional

Este documento NO incluye implementación. Solo diseño arquitectónico.


1 OBJETIVO DEL PANEL

Principio Rector

"Se edita CONTENIDO, no CONTINENTE"

El panel permite modificar:

  • Textos de protocolos
  • Dosis de fármacos
  • Notas clínicas
  • Advertencias
  • Observaciones
  • Bloques formativos (Markdown)

El panel NO permite modificar:

  • Componentes React
  • Estructura visual
  • Lógica de la app
  • Rutas y navegación
  • Service Worker

Casos de Uso Principales

  1. Editor Clínico:

    • Actualizar dosis según nuevas guías (ERC, AHA, SEMES)
    • Añadir advertencias críticas
    • Modificar pasos de protocolos
  2. Editor Docente:

    • Crear nuevas guías formativas
    • Modificar casos clínicos
    • Actualizar explicaciones fisiopatológicas
  3. Administrador Institucional:

    • Validar contenido antes de publicación
    • Revisar historial de cambios
    • Activar/desactivar contenido

2 ARQUITECTURA PROPUESTA

Modelo de Separación: Contenido vs Aplicación

┌─────────────────────────────────────────────────────────┐
│              APLICACIÓN (React - Estática)               │
│  - Componentes React (NO editables)                     │
│  - Lógica de UI (NO editable)                          │
│  - Service Worker (NO editable)                         │
│  - Estructura de navegación (NO editable)               │
└─────────────────────────────────────────────────────────┘
                        │
                        │ Carga dinámica
                        │
                        ▼
┌─────────────────────────────────────────────────────────┐
│         CONTENIDO (JSON/Markdown - Dinámico)            │
│  - Protocolos (JSON)                                    │
│  - Fármacos (JSON)                                      │
│  - Guías formativas (Markdown)                          │
│  - Manual completo (Markdown)                           │
└─────────────────────────────────────────────────────────┘
                        │
                        │ Edición
                        │
                        ▼
┌─────────────────────────────────────────────────────────┐
│         PANEL DE ADMINISTRACIÓN (Web App)               │
│  - Editor de contenido                                  │
│  - Validación clínica                                   │
│  - Control de versiones                                 │
│  - Gestión de usuarios                                  │
└─────────────────────────────────────────────────────────┘

Flujo de Datos

1. Panel Admin → Edita contenido → Guarda en backend/API
2. Backend → Valida → Versiona → Almacena
3. App → Solicita contenido → Backend → Entrega JSON/Markdown
4. App → Cachea localmente → Funciona offline
5. App → Detecta actualizaciones → Notifica usuario

Arquitectura de Capas

Capa 1: Almacenamiento de Contenido

Opciones técnicas:

Opción A: Sistema de Archivos Versionado (Git-based)

  • Contenido en repositorio Git
  • Panel edita archivos JSON/Markdown
  • Commits automáticos con versionado
  • Ventaja: Historial completo, rollback fácil
  • Desventaja: Requiere servidor Git

Opción B: Base de Datos + API REST

  • Contenido en base de datos (PostgreSQL, MongoDB)
  • API REST para CRUD de contenido
  • Panel consume API
  • Ventaja: Escalable, flexible
  • Desventaja: Más complejo, requiere backend

Opción C: Headless CMS (Strapi, Contentful, Sanity)

  • CMS especializado en contenido
  • Panel integrado
  • API automática
  • Ventaja: Rápido de implementar
  • Desventaja: Dependencia externa, coste

Recomendación: Opción A (Git-based) para MVP, migrar a Opción B si escala.


Capa 2: API de Contenido

Endpoints propuestos:

GET  /api/content/protocols          → Lista todos los protocolos
GET  /api/content/protocols/:id       → Protocolo específico
PUT  /api/content/protocols/:id      → Actualizar protocolo
POST /api/content/protocols           → Crear protocolo

GET  /api/content/drugs               → Lista todos los fármacos
GET  /api/content/drugs/:id            → Fármaco específico
PUT  /api/content/drugs/:id            → Actualizar fármaco

GET  /api/content/guides/:id/sections/:num → Sección de guía
PUT  /api/content/guides/:id/sections/:num → Actualizar sección

GET  /api/content/manual/blocks/:id    → Bloque del manual
PUT  /api/content/manual/blocks/:id    → Actualizar bloque

GET  /api/content/versions/:id        → Historial de versiones
GET  /api/content/versions/:id/:version → Versión específica

Capa 3: Panel de Administración

Tecnología propuesta:

  • Framework: React (consistente con app principal)
  • UI: shadcn/ui (consistente con app principal)
  • Editor Markdown: react-markdown-editor-lite o similar
  • Validación: Zod (TypeScript-first)

Estructura propuesta:

admin-panel/
├── src/
│   ├── pages/
│   │   ├── ProtocolsEditor.tsx      → Editor de protocolos
│   │   ├── DrugsEditor.tsx           → Editor de fármacos
│   │   ├── GuidesEditor.tsx          → Editor de guías
│   │   ├── ManualEditor.tsx           → Editor de manual
│   │   └── Validation.tsx             → Panel de validación
│   ├── components/
│   │   ├── ContentEditor/            → Componentes de edición
│   │   ├── Validation/                → Componentes de validación
│   │   └── VersionHistory/           → Historial de versiones
│   └── lib/
│       ├── api.ts                     → Cliente API
│       └── validation.ts               → Reglas de validación

Capa 4: Aplicación Principal (Consumidora)

Modificaciones necesarias:

  1. Carga dinámica de contenido:

    // Antes (estático)
    import { procedures } from '@/data/procedures';
    
    // Después (dinámico)
    const procedures = await fetchContent('protocols');
    
  2. Cache local:

    // Cache en IndexedDB o localStorage
    const cachedContent = await getCachedContent('protocols');
    if (cachedContent && !isStale(cachedContent)) {
      return cachedContent;
    }
    const freshContent = await fetchContent('protocols');
    await cacheContent('protocols', freshContent);
    return freshContent;
    
  3. Detección de actualizaciones:

    // Verificar versiones periódicamente
    const latestVersion = await checkContentVersion();
    if (latestVersion > cachedVersion) {
      showUpdateNotification();
    }
    

3 FUNCIONALIDADES DEL PANEL

3.1 Gestión de Contenido

Editor de Protocolos

Campos editables:

  • Título
  • Pasos (array de strings)
  • Advertencias (array de strings)
  • Puntos clave (array de strings)
  • Material necesario (array de strings)
  • Fármacos relacionados (array de IDs)

Validación:

  • Pasos no pueden estar vacíos
  • Advertencias máx. 5
  • IDs de fármacos deben existir

UI propuesta:

┌─────────────────────────────────────────┐
│ Editor de Protocolo: RCP Adulto SVB     │
├─────────────────────────────────────────┤
│ Título: [RCP Adulto - Soporte Vital...] │
│                                         │
│ Pasos:                                  │
│ [1] [Garantizar seguridad de la escena]│
│ [2] [Comprobar consciencia...]         │
│ [+] Añadir paso                         │
│                                         │
│ Advertencias:                           │
│ [•] [Profundidad compresiones: 5-6 cm] │
│ [+] Añadir advertencia                 │
│                                         │
│ [Guardar] [Cancelar] [Validar]          │
└─────────────────────────────────────────┘

Editor de Fármacos

Campos editables:

  • Nombre genérico
  • Nombre comercial
  • Dosis adulto
  • Dosis pediátrica
  • Vías de administración
  • Dilución
  • Indicaciones
  • Contraindicaciones
  • Efectos secundarios
  • Notas clínicas
  • Puntos críticos TES

Validación:

  • Dosis debe tener formato válido
  • Vías deben ser del enum permitido
  • Indicaciones/contraindicaciones no pueden estar vacías

Editor de Guías Formativas

Editor Markdown con preview:

  • Editor dividido (Markdown | Preview)
  • Soporte para imágenes
  • Validación de estructura (8 secciones)
  • Metadatos (título, descripción, icono)

Editor de Manual

Editor Markdown completo:

  • Editor Markdown avanzado
  • Navegación por bloques
  • Búsqueda y reemplazo
  • Validación de referencias cruzadas

3.2 Control Sanitario

Campos de Validación

Cada contenido editable debe tener:

interface ContentMetadata {
  // Identificación
  id: string;                    // ID único e inmutable
  version: number;                // Versión incremental
  
  // Validación clínica
  validatedBy?: string;            // ID del validador
  validatedAt?: Date;              // Fecha de validación
  clinicalSource?: string;         // ERC, AHA, SEMES, etc.
  validationStatus: 'draft' | 'pending' | 'validated' | 'rejected';
  
  // Control de calidad
  reviewedBy?: string;             // ID del revisor
  reviewedAt?: Date;               // Fecha de revisión
  qualityScore?: number;            // 0-100
  
  // Historial
  createdAt: Date;                 // Fecha de creación
  createdBy: string;                // ID del creador
  updatedAt: Date;                 // Fecha de última actualización
  updatedBy: string;                // ID del último editor
  changeLog: ChangeLogEntry[];     // Historial de cambios
}

Flujo de Validación

1. Editor → Crea/Modifica contenido → Estado: "draft"
2. Editor → Solicita validación → Estado: "pending"
3. Validador → Revisa contenido → Acepta/Rechaza
4. Si acepta → Estado: "validated" → Publicable
5. Si rechaza → Estado: "rejected" → Vuelve a "draft"

3.3 Seguridad y Roles

Roles Propuestos

1. Administrador Clínico:

  • Validar contenido clínico
  • Aprobar/rechazar cambios
  • Acceso a historial completo
  • No puede editar contenido directamente

2. Editor Docente:

  • Crear/editar guías formativas
  • Crear/editar manual
  • Modificar casos clínicos
  • No puede validar contenido clínico
  • No puede modificar protocolos operativos

3. Editor Clínico:

  • Crear/editar protocolos operativos
  • Crear/editar vademécum
  • Modificar dosis y advertencias
  • No puede validar (debe solicitar validación)

4. Revisor:

  • Revisar contenido pendiente
  • Sugerir cambios
  • No puede editar directamente
  • No puede validar

Autenticación y Autorización

Propuesta:

  • Autenticación: JWT tokens
  • Autorización: RBAC (Role-Based Access Control)
  • Auditoría: Log de todas las acciones

Endpoints protegidos:

POST /api/auth/login              → Autenticación
POST /api/auth/logout             → Cerrar sesión
GET  /api/auth/me                 → Información del usuario

GET  /api/content/*               → Lectura (público o autenticado)
PUT  /api/content/*               → Escritura (requiere rol)
POST /api/content/*               → Creación (requiere rol)
DELETE /api/content/*             → Eliminación (solo admin)

4 COMPATIBILIDAD OFFLINE

Estrategia de Cache

Principio: "El último contenido válido siempre está disponible offline"

Implementación:

  1. Cache inicial (build time):

    • Contenido embebido en la app (fallback)
    • Se genera en build time desde fuente de verdad
  2. Cache dinámico (runtime):

    • App solicita contenido al iniciar
    • Si hay red: Descarga y cachea
    • Si no hay red: Usa cache local
    • Cache se actualiza en background cuando hay red
  3. Versionado de cache:

    interface CachedContent {
      content: any;
      version: number;
      cachedAt: Date;
      expiresAt: Date;
    }
    
  4. Invalidación de cache:

    • Por tiempo: Cache expira después de X días
    • Por versión: Si versión remota > versión local
    • Manual: Usuario puede forzar actualización

Flujo Offline-First

App inicia
  │
  ├─ ¿Hay red?
  │   │
  │   ├─ SÍ → Solicitar contenido actualizado
  │   │        │
  │   │        ├─ ¿Hay actualización?
  │   │        │   │
  │   │        │   ├─ SÍ → Descargar y cachear
  │   │        │   │        Mostrar contenido actualizado
  │   │        │   │
  │   │        │   └─ NO → Usar cache local
  │   │        │
  │   │        └─ Si falla → Usar cache local
  │   │
  │   └─ NO → Usar cache local
  │
  └─ Mostrar contenido (siempre funciona)

5 MODELO DE DATOS CONCEPTUAL

Estructura de Contenido Editable

Protocolo Operativo:

{
  "id": "rcp-adulto-svb",
  "version": 3,
  "title": "RCP Adulto - Soporte Vital Básico",
  "shortTitle": "RCP Adulto SVB",
  "category": "soporte_vital",
  "priority": "critico",
  "steps": [
    "Garantizar seguridad de la escena",
    "Comprobar consciencia..."
  ],
  "warnings": [
    "Profundidad compresiones: 5-6 cm",
    "Frecuencia: 100-120 compresiones/min"
  ],
  "keyPoints": [...],
  "equipment": [...],
  "drugs": [...],
  "metadata": {
    "validatedBy": "dr-juan-perez",
    "validatedAt": "2025-01-15T10:00:00Z",
    "clinicalSource": "ERC 2021",
    "validationStatus": "validated"
  }
}

Fármaco:

{
  "id": "adrenalina",
  "version": 5,
  "genericName": "Adrenalina (Epinefrina)",
  "tradeName": "Adrenalina Braun®",
  "adultDose": "ANAFILAXIA: 0.5 mg IM...",
  "pediatricDose": "ANAFILAXIA: 0.01 mg/kg IM...",
  "routes": ["IM", "IV", "IO"],
  "dilution": "ANAFILAXIA: Sin diluir...",
  "indications": [...],
  "contraindications": [...],
  "notes": [...],
  "criticalPoints": [...],
  "metadata": {...}
}

Guía Formativa (Sección):

{
  "guideId": "rcp-adulto-svb",
  "sectionNumber": 1,
  "version": 2,
  "title": "Introducción y Contexto",
  "content": "# SECCIÓN 1: Introducción...\n\n[Markdown completo]",
  "metadata": {...}
}

6 SEGURIDAD Y AUDITORÍA

Logging y Auditoría

Todas las acciones deben registrarse:

interface AuditLog {
  id: string;
  timestamp: Date;
  userId: string;
  action: 'create' | 'update' | 'delete' | 'validate' | 'reject';
  resourceType: 'protocol' | 'drug' | 'guide' | 'manual';
  resourceId: string;
  changes?: {
    field: string;
    oldValue: any;
    newValue: any;
  }[];
  ipAddress?: string;
  userAgent?: string;
}

Protección de Datos

Requisitos:

  • Contenido sanitario es sensible
  • Debe cumplir protección de datos (RGPD si aplica)
  • Historial de cambios debe ser inmutable
  • Backups regulares

7 ESCALABILIDAD INSTITUCIONAL

Multi-tenancy (Futuro)

Si escala a múltiples instituciones:

  • Cada institución tiene su propio contenido
  • Panel permite seleccionar institución
  • Contenido puede ser compartido o privado
  • Roles por institución

API Pública (Futuro)

Para integración con otros sistemas:

  • API REST pública (read-only)
  • Autenticación por API key
  • Rate limiting
  • Documentación OpenAPI/Swagger

📋 RESUMEN EJECUTIVO

Arquitectura propuesta:

  • Separación: Contenido (dinámico) vs Aplicación (estática)
  • Almacenamiento: Git-based (MVP) → Base de datos (escala)
  • Panel: React + shadcn/ui (consistente con app)
  • API: REST para CRUD de contenido
  • Cache: Offline-first con versionado

Funcionalidades:

  • Editor de protocolos, fármacos, guías, manual
  • Validación clínica con roles
  • Historial de versiones
  • Auditoría completa

Seguridad:

  • Autenticación JWT
  • Autorización RBAC
  • Logging de auditoría
  • Protección de datos

Compatibilidad:

  • Offline-first garantizado
  • Cache local con versionado
  • Fallback a contenido embebido

Este documento es el diseño arquitectónico. La implementación se realizará en fases según el roadmap.