635 lines
18 KiB
Markdown
635 lines
18 KiB
Markdown
# 🏗️ 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.**
|
||
|