codigo0/docs/ARQUITECTURA_PANEL_ADMIN.md

635 lines
18 KiB
Markdown
Raw Normal View History

2026-01-19 08:10:16 +00:00
# 🏗️ 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:**
```typescript
// Antes (estático)
import { procedures } from '@/data/procedures';
// Después (dinámico)
const procedures = await fetchContent('protocols');
```
2. **Cache local:**
```typescript
// 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:**
```typescript
// 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:**
```typescript
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:**
```typescript
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:**
```json
{
"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:**
```json
{
"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):**
```json
{
"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:**
```typescript
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.**