622 lines
15 KiB
Markdown
622 lines
15 KiB
Markdown
# 📊 MODELO DE DATOS DE CONTENIDO - EMERGES TES
|
||
|
||
**Versión:** 1.0
|
||
**Fecha:** 2025-01-XX
|
||
**Estado:** Documento de Especificación - Sin Implementación
|
||
**Autor:** Arquitecto de Software Senior + Arquitecto de Contenido
|
||
|
||
---
|
||
|
||
## 🎯 PROPÓSITO DEL DOCUMENTO
|
||
|
||
Este documento define **EL MODELO DE DATOS CONCEPTUAL** para el sistema de gestión de contenido de EMERGES TES. Especifica:
|
||
|
||
- ✅ Estructura de datos para contenido editable
|
||
- ✅ IDs estables e inmutables
|
||
- ✅ Sistema de versionado
|
||
- ✅ Metadatos de validación clínica
|
||
- ✅ Relaciones entre entidades
|
||
|
||
**Este documento es la especificación técnica para implementación futura.**
|
||
|
||
---
|
||
|
||
## 1️⃣ PRINCIPIOS DE DISEÑO
|
||
|
||
### Principio 1: IDs Estables e Inmutables
|
||
|
||
**Cada entidad de contenido tiene un ID único que:**
|
||
- ✅ No cambia nunca (inmutable)
|
||
- ✅ No depende del texto o título
|
||
- ✅ Es legible y descriptivo
|
||
- ✅ Sigue convención consistente
|
||
|
||
**Convención de IDs:**
|
||
- Protocolos: `{tema}-{variante}` (ej: `rcp-adulto-svb`)
|
||
- Fármacos: `{nombre-generico-lowercase}` (ej: `adrenalina`)
|
||
- Guías: `{tema}-{variante}` (ej: `rcp-adulto-svb`)
|
||
- Manual: `{bloque}-{subbloque}` (ej: `bloque-04-1`)
|
||
|
||
---
|
||
|
||
### Principio 2: Versionado Semántico
|
||
|
||
**Cada contenido tiene versión que:**
|
||
- ✅ Incrementa en cada cambio
|
||
- ✅ Permite rollback
|
||
- ✅ Facilita auditoría
|
||
- ✅ Soporta comparación de versiones
|
||
|
||
**Formato:** Número entero incremental (1, 2, 3, ...)
|
||
|
||
---
|
||
|
||
### Principio 3: Separación de Contenido y Metadatos
|
||
|
||
**Contenido (editable):**
|
||
- Textos, pasos, dosis, explicaciones
|
||
|
||
**Metadatos (sistema):**
|
||
- IDs, versiones, validación, auditoría
|
||
|
||
**Ventaja:** Permite editar contenido sin tocar metadatos del sistema.
|
||
|
||
---
|
||
|
||
## 2️⃣ MODELO DE DATOS POR TIPO
|
||
|
||
### 2.1 Protocolo Operativo
|
||
|
||
```typescript
|
||
interface Protocol {
|
||
// Identificación (inmutable)
|
||
id: string; // "rcp-adulto-svb"
|
||
version: number; // 1, 2, 3...
|
||
|
||
// Contenido (editable)
|
||
title: string; // "RCP Adulto - Soporte Vital Básico"
|
||
shortTitle: string; // "RCP Adulto SVB"
|
||
category: 'soporte_vital' | 'patologias' | 'escena';
|
||
subcategory?: string; // "rcp"
|
||
priority: 'critico' | 'alto' | 'medio' | 'bajo';
|
||
ageGroup: 'adulto' | 'pediatrico' | 'neonatal' | 'todos';
|
||
|
||
// Pasos del protocolo (editable)
|
||
steps: string[]; // Array de pasos numerados
|
||
|
||
// Advertencias (editable)
|
||
warnings: string[]; // Máx. 5 advertencias críticas
|
||
|
||
// Puntos clave (editable)
|
||
keyPoints?: string[]; // Puntos importantes
|
||
|
||
// Material necesario (editable)
|
||
equipment?: string[]; // Lista de material
|
||
|
||
// Fármacos relacionados (referencias)
|
||
drugs?: string[]; // IDs de fármacos: ["adrenalina", "amiodarona"]
|
||
|
||
// Metadatos del sistema (no editable directamente)
|
||
metadata: ContentMetadata;
|
||
}
|
||
```
|
||
|
||
**Ejemplo JSON:**
|
||
```json
|
||
{
|
||
"id": "rcp-adulto-svb",
|
||
"version": 3,
|
||
"title": "RCP Adulto - Soporte Vital Básico",
|
||
"shortTitle": "RCP Adulto SVB",
|
||
"category": "soporte_vital",
|
||
"subcategory": "rcp",
|
||
"priority": "critico",
|
||
"ageGroup": "adulto",
|
||
"steps": [
|
||
"Garantizar seguridad de la escena",
|
||
"Comprobar consciencia: estimular y preguntar \"¿Se encuentra bien?\"",
|
||
"Si no responde, llamar inmediatamente al 112"
|
||
],
|
||
"warnings": [
|
||
"Profundidad compresiones: 5-6 cm",
|
||
"Frecuencia: 100-120 compresiones/min"
|
||
],
|
||
"keyPoints": [
|
||
"Compresiones de calidad salvan vidas",
|
||
"No interrumpir para pulso hasta que haya signos de vida"
|
||
],
|
||
"equipment": ["DEA", "Bolsa-mascarilla", "Cánula orofaríngea"],
|
||
"drugs": ["adrenalina"],
|
||
"metadata": {
|
||
"validatedBy": "dr-juan-perez",
|
||
"validatedAt": "2025-01-15T10:00:00Z",
|
||
"clinicalSource": "ERC 2021",
|
||
"validationStatus": "validated",
|
||
"createdAt": "2024-12-01T08:00:00Z",
|
||
"createdBy": "editor-clinico-001",
|
||
"updatedAt": "2025-01-15T10:00:00Z",
|
||
"updatedBy": "editor-clinico-001",
|
||
"changeLog": [...]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2.2 Fármaco (Vademécum)
|
||
|
||
```typescript
|
||
interface Drug {
|
||
// Identificación (inmutable)
|
||
id: string; // "adrenalina"
|
||
version: number; // 1, 2, 3...
|
||
|
||
// Contenido (editable)
|
||
genericName: string; // "Adrenalina (Epinefrina)"
|
||
tradeName: string; // "Adrenalina Braun®"
|
||
category: 'cardiovascular' | 'respiratorio' | 'neurologico' | 'analgesia' | 'oxigenoterapia' | 'otros';
|
||
presentation: string; // Descripción de presentación
|
||
|
||
// Dosis (editable - crítico)
|
||
adultDose: string; // "ANAFILAXIA: 0.5 mg IM..."
|
||
pediatricDose?: string; // "ANAFILAXIA: 0.01 mg/kg IM..."
|
||
|
||
// Vías de administración (editable)
|
||
routes: ('IV' | 'IM' | 'SC' | 'IO' | 'Nebulizado' | 'SL' | 'Rectal' | 'Nasal')[];
|
||
|
||
// Dilución (editable)
|
||
dilution?: string; // "ANAFILAXIA: Sin diluir..."
|
||
|
||
// Indicaciones (editable)
|
||
indications: string[]; // Array de indicaciones
|
||
|
||
// Contraindicaciones (editable)
|
||
contraindications: string[]; // Array de contraindicaciones
|
||
|
||
// Efectos secundarios (editable)
|
||
sideEffects?: string[]; // Array de efectos secundarios
|
||
|
||
// Antídoto (editable)
|
||
antidote?: string; // Antídoto si aplica
|
||
|
||
// Notas clínicas (editable)
|
||
notes?: string[]; // Notas importantes
|
||
|
||
// Puntos críticos TES (editable)
|
||
criticalPoints?: string[]; // Errores críticos a evitar
|
||
|
||
// Fuente (editable)
|
||
source?: string; // "BLOQUE_06_1_VADEMECUM_OPERATIVO.md"
|
||
|
||
// Metadatos del sistema
|
||
metadata: ContentMetadata;
|
||
}
|
||
```
|
||
|
||
**Ejemplo JSON:**
|
||
```json
|
||
{
|
||
"id": "adrenalina",
|
||
"version": 5,
|
||
"genericName": "Adrenalina (Epinefrina)",
|
||
"tradeName": "Adrenalina Braun®",
|
||
"category": "cardiovascular",
|
||
"presentation": "ANAFILAXIA: Ampolla 1 mg/1 ml (1:1000)...",
|
||
"adultDose": "ANAFILAXIA: 0.5 mg IM (0.5 ml de ampolla 1:1000)...",
|
||
"pediatricDose": "ANAFILAXIA: 0.01 mg/kg IM (Máx. 0.5 mg)...",
|
||
"routes": ["IM", "IV", "IO"],
|
||
"dilution": "ANAFILAXIA: Sin diluir. PCR: Sin diluir...",
|
||
"indications": [
|
||
"Anafilaxia grave: Reacción alérgica sistémica...",
|
||
"Parada cardiorrespiratoria: Cualquier ritmo..."
|
||
],
|
||
"contraindications": [
|
||
"No hay contraindicaciones absolutas en emergencias vitales"
|
||
],
|
||
"sideEffects": ["Temblor", "Taquicardia", "Palidez"],
|
||
"notes": [
|
||
"⚠️ CONCENTRACIÓN CRÍTICA: 1:1000 (1 mg/ml) para Anafilaxia IM..."
|
||
],
|
||
"criticalPoints": [
|
||
"⚠️ ERROR CRÍTICO: Confundir 1:1000 con 1:10.000..."
|
||
],
|
||
"source": "BLOQUE_06_1_VADEMECUM_OPERATIVO.md",
|
||
"metadata": {...}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2.3 Guía Formativa (Sección)
|
||
|
||
```typescript
|
||
interface GuideSection {
|
||
// Identificación (inmutable)
|
||
guideId: string; // "rcp-adulto-svb"
|
||
sectionNumber: number; // 1-8
|
||
version: number; // 1, 2, 3...
|
||
|
||
// Contenido (editable)
|
||
title: string; // "Introducción y Contexto"
|
||
content: string; // Markdown completo de la sección
|
||
|
||
// Metadatos del sistema
|
||
metadata: ContentMetadata;
|
||
}
|
||
```
|
||
|
||
**Ejemplo JSON:**
|
||
```json
|
||
{
|
||
"guideId": "rcp-adulto-svb",
|
||
"sectionNumber": 1,
|
||
"version": 2,
|
||
"title": "Introducción y Contexto",
|
||
"content": "# SECCIÓN 1: Introducción y Contexto\n\n**Guía de Refuerzo — RCP Adulto SVB**\n\n---\n\n## Bloque 1: Texto Explicativo\n\n...",
|
||
"metadata": {...}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2.4 Manual Completo (Bloque)
|
||
|
||
```typescript
|
||
interface ManualBlock {
|
||
// Identificación (inmutable)
|
||
blockId: string; // "bloque-04-1"
|
||
version: number; // 1, 2, 3...
|
||
|
||
// Contenido (editable)
|
||
title: string; // "RCP Adultos"
|
||
content: string; // Markdown completo del bloque
|
||
|
||
// Estructura
|
||
parentBlock?: string; // Bloque padre (si aplica)
|
||
order: number; // Orden dentro del bloque padre
|
||
|
||
// Metadatos del sistema
|
||
metadata: ContentMetadata;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2.5 Metadatos Comunes
|
||
|
||
```typescript
|
||
interface ContentMetadata {
|
||
// Validación clínica
|
||
validatedBy?: string; // ID del validador (ej: "dr-juan-perez")
|
||
validatedAt?: Date; // Fecha de validación ISO 8601
|
||
clinicalSource?: string; // "ERC 2021", "AHA 2020", "SEMES 2022"
|
||
validationStatus: 'draft' | 'pending' | 'validated' | 'rejected';
|
||
|
||
// Control de calidad
|
||
reviewedBy?: string; // ID del revisor
|
||
reviewedAt?: Date; // Fecha de revisión
|
||
qualityScore?: number; // 0-100 (opcional)
|
||
|
||
// Historial
|
||
createdAt: Date; // Fecha de creación ISO 8601
|
||
createdBy: string; // ID del creador
|
||
updatedAt: Date; // Fecha de última actualización
|
||
updatedBy: string; // ID del último editor
|
||
|
||
// Historial de cambios
|
||
changeLog: ChangeLogEntry[]; // Array de cambios
|
||
}
|
||
|
||
interface ChangeLogEntry {
|
||
version: number; // Versión del cambio
|
||
timestamp: Date; // Fecha del cambio
|
||
userId: string; // ID del usuario que hizo el cambio
|
||
action: 'create' | 'update' | 'delete' | 'validate' | 'reject';
|
||
changes: {
|
||
field: string; // Campo modificado
|
||
oldValue?: any; // Valor anterior (si aplica)
|
||
newValue?: any; // Valor nuevo
|
||
}[];
|
||
comment?: string; // Comentario del cambio
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 3️⃣ RELACIONES ENTRE ENTIDADES
|
||
|
||
### Relación: Protocolo → Fármacos
|
||
|
||
**Tipo:** Referencia (no embebida)
|
||
|
||
**Implementación:**
|
||
```typescript
|
||
// En Protocol
|
||
drugs?: string[]; // ["adrenalina", "amiodarona"]
|
||
|
||
// Resolución
|
||
const protocolDrugs = protocol.drugs?.map(drugId =>
|
||
drugs.find(d => d.id === drugId)
|
||
);
|
||
```
|
||
|
||
**Ventaja:** Si se actualiza un fármaco, todos los protocolos que lo referencian se actualizan automáticamente.
|
||
|
||
---
|
||
|
||
### Relación: Protocolo → Guía Formativa
|
||
|
||
**Tipo:** Mapeo explícito (no embebida)
|
||
|
||
**Implementación:**
|
||
```typescript
|
||
// En protocol-guide-manual-mapping.ts
|
||
{
|
||
protocoloId: "rcp-adulto-svb",
|
||
guiaId: "rcp-adulto-svb",
|
||
tieneGuia: true
|
||
}
|
||
```
|
||
|
||
**Ventaja:** Permite que protocolos y guías evolucionen independientemente.
|
||
|
||
---
|
||
|
||
### Relación: Guía → Manual
|
||
|
||
**Tipo:** Mapeo explícito (no embebida)
|
||
|
||
**Implementación:**
|
||
```typescript
|
||
// En protocol-guide-manual-mapping.ts
|
||
{
|
||
guiaId: "rcp-adulto-svb",
|
||
manualBloque: "BLOQUE_04_1",
|
||
tieneManual: true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 4️⃣ SISTEMA DE VERSIONADO
|
||
|
||
### Versionado de Contenido
|
||
|
||
**Estrategia:** Versionado incremental por entidad
|
||
|
||
**Reglas:**
|
||
1. Cada cambio incrementa la versión
|
||
2. Versiones anteriores se mantienen (historial)
|
||
3. Solo la última versión validada es "activa"
|
||
4. Rollback permite restaurar versiones anteriores
|
||
|
||
**Ejemplo:**
|
||
```
|
||
Protocolo: rcp-adulto-svb
|
||
v1 (2024-12-01): Creación inicial
|
||
v2 (2025-01-10): Actualización de pasos según ERC 2021
|
||
v3 (2025-01-15): Añadida advertencia sobre profundidad
|
||
v3 (activa) ← Versión actual
|
||
```
|
||
|
||
---
|
||
|
||
### Comparación de Versiones
|
||
|
||
**Funcionalidad:** Permite ver diferencias entre versiones
|
||
|
||
**Implementación:**
|
||
```typescript
|
||
interface VersionDiff {
|
||
version1: number;
|
||
version2: number;
|
||
changes: {
|
||
field: string;
|
||
oldValue: any;
|
||
newValue: any;
|
||
}[];
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5️⃣ VALIDACIÓN Y ESQUEMAS
|
||
|
||
### Esquemas de Validación
|
||
|
||
**Propuesta:** JSON Schema o Zod (TypeScript)
|
||
|
||
**Ejemplo con Zod:**
|
||
```typescript
|
||
import { z } from 'zod';
|
||
|
||
const ProtocolSchema = z.object({
|
||
id: z.string().regex(/^[a-z0-9-]+$/),
|
||
version: z.number().int().positive(),
|
||
title: z.string().min(1).max(200),
|
||
steps: z.array(z.string().min(1)).min(1),
|
||
warnings: z.array(z.string()).max(5),
|
||
metadata: ContentMetadataSchema
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
### Validación en Panel
|
||
|
||
**Antes de guardar:**
|
||
1. Validar estructura (schema)
|
||
2. Validar reglas de negocio (ej: máx. 5 advertencias)
|
||
3. Validar referencias (ej: fármacos deben existir)
|
||
4. Si pasa validación → Permitir guardar
|
||
5. Si falla → Mostrar errores
|
||
|
||
---
|
||
|
||
## 6️⃣ ALMACENAMIENTO
|
||
|
||
### Opción 1: Archivos JSON (Git-based)
|
||
|
||
**Estructura:**
|
||
```
|
||
content/
|
||
├── protocols/
|
||
│ ├── rcp-adulto-svb.json
|
||
│ ├── rcp-adulto-sva.json
|
||
│ └── ...
|
||
├── drugs/
|
||
│ ├── adrenalina.json
|
||
│ ├── amiodarona.json
|
||
│ └── ...
|
||
├── guides/
|
||
│ ├── rcp-adulto-svb/
|
||
│ │ ├── section-01.json
|
||
│ │ ├── section-02.json
|
||
│ │ └── ...
|
||
│ └── ...
|
||
└── manual/
|
||
├── bloque-04-1.json
|
||
└── ...
|
||
```
|
||
|
||
**Ventaja:** Versionado automático con Git, historial completo
|
||
|
||
---
|
||
|
||
### Opción 2: Base de Datos
|
||
|
||
**Tablas propuestas:**
|
||
```sql
|
||
-- Protocolos
|
||
CREATE TABLE protocols (
|
||
id VARCHAR(100) PRIMARY KEY,
|
||
version INT NOT NULL,
|
||
content JSONB NOT NULL,
|
||
metadata JSONB NOT NULL,
|
||
created_at TIMESTAMP,
|
||
updated_at TIMESTAMP
|
||
);
|
||
|
||
-- Fármacos
|
||
CREATE TABLE drugs (
|
||
id VARCHAR(100) PRIMARY KEY,
|
||
version INT NOT NULL,
|
||
content JSONB NOT NULL,
|
||
metadata JSONB NOT NULL,
|
||
created_at TIMESTAMP,
|
||
updated_at TIMESTAMP
|
||
);
|
||
|
||
-- Guías (secciones)
|
||
CREATE TABLE guide_sections (
|
||
guide_id VARCHAR(100),
|
||
section_number INT,
|
||
version INT NOT NULL,
|
||
content JSONB NOT NULL,
|
||
metadata JSONB NOT NULL,
|
||
PRIMARY KEY (guide_id, section_number, version)
|
||
);
|
||
|
||
-- Historial de versiones
|
||
CREATE TABLE content_versions (
|
||
id SERIAL PRIMARY KEY,
|
||
content_type VARCHAR(50), -- 'protocol', 'drug', 'guide', 'manual'
|
||
content_id VARCHAR(100),
|
||
version INT,
|
||
content JSONB,
|
||
created_at TIMESTAMP,
|
||
created_by VARCHAR(100)
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## 7️⃣ MIGRACIÓN DESDE ESTRUCTURA ACTUAL
|
||
|
||
### Mapeo de Archivos Actuales
|
||
|
||
**Protocolos:**
|
||
```
|
||
src/data/procedures.ts
|
||
→ content/protocols/*.json
|
||
```
|
||
|
||
**Fármacos:**
|
||
```
|
||
src/data/drugs.ts
|
||
→ content/drugs/*.json
|
||
```
|
||
|
||
**Guías:**
|
||
```
|
||
docs/consolidado/SECCION_XX_*.md
|
||
→ content/guides/{guideId}/section-{num}.json
|
||
```
|
||
|
||
**Manual:**
|
||
```
|
||
public/manual/BLOQUE_XX_*/*.md
|
||
→ content/manual/bloque-{id}.json
|
||
```
|
||
|
||
---
|
||
|
||
### Script de Migración (Conceptual)
|
||
|
||
```typescript
|
||
// 1. Leer procedures.ts
|
||
const procedures = require('./src/data/procedures.ts');
|
||
|
||
// 2. Convertir a formato JSON
|
||
procedures.forEach(proc => {
|
||
const protocolJson = {
|
||
id: proc.id,
|
||
version: 1,
|
||
...proc,
|
||
metadata: {
|
||
validationStatus: 'validated',
|
||
createdAt: new Date().toISOString(),
|
||
createdBy: 'migration-script',
|
||
changeLog: []
|
||
}
|
||
};
|
||
|
||
// 3. Guardar en content/protocols/
|
||
fs.writeFileSync(
|
||
`content/protocols/${proc.id}.json`,
|
||
JSON.stringify(protocolJson, null, 2)
|
||
);
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## 📋 RESUMEN EJECUTIVO
|
||
|
||
**Modelo de datos:**
|
||
- ✅ IDs estables e inmutables
|
||
- ✅ Versionado incremental
|
||
- ✅ Separación contenido/metadatos
|
||
- ✅ Relaciones por referencia (no embebidas)
|
||
|
||
**Entidades principales:**
|
||
- Protocol (Protocolo Operativo)
|
||
- Drug (Fármaco)
|
||
- GuideSection (Sección de Guía)
|
||
- ManualBlock (Bloque de Manual)
|
||
|
||
**Metadatos comunes:**
|
||
- Validación clínica
|
||
- Control de calidad
|
||
- Historial de cambios
|
||
- Auditoría
|
||
|
||
**Almacenamiento:**
|
||
- Opción 1: Archivos JSON (Git-based) - MVP
|
||
- Opción 2: Base de datos - Escala
|
||
|
||
---
|
||
|
||
**Este documento es la especificación técnica para implementación futura del sistema de gestión de contenido.**
|
||
|