456 lines
12 KiB
Markdown
456 lines
12 KiB
Markdown
|
|
# 💊 MÓDULO VADEMÉCUM TES - DOCUMENTACIÓN DE IMPLEMENTACIÓN
|
||
|
|
|
||
|
|
**Proyecto:** Guía TES - Sistema de Gestión de Contenido
|
||
|
|
**Fecha:** 2025-01-07
|
||
|
|
**Estado:** ✅ IMPLEMENTACIÓN COMPLETA
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎯 OBJETIVO
|
||
|
|
|
||
|
|
Implementar un módulo completo de Vademécum TES (35 fármacos) en un sistema de contenido self-hosted (PostgreSQL) sin romper la app actual.
|
||
|
|
|
||
|
|
**Características clave:**
|
||
|
|
- ✅ Solo capa de **REFERENCIA** (no operativa ni formativa)
|
||
|
|
- ✅ Self-hosted (PostgreSQL, sin servicios externos)
|
||
|
|
- ✅ No modifica código existente (arquitectura aditiva)
|
||
|
|
- ✅ Versionado completo
|
||
|
|
- ✅ Workflow de validación
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📐 ARQUITECTURA
|
||
|
|
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────────────┐
|
||
|
|
│ Panel Admin (/drugs) │
|
||
|
|
│ - DrugManagerPage (lista) │
|
||
|
|
│ - DrugEditorPage (editor) │
|
||
|
|
└────────────────────┬────────────────────────────────────┘
|
||
|
|
│
|
||
|
|
▼
|
||
|
|
┌─────────────────────────────────────────────────────────┐
|
||
|
|
│ API REST (/api/drugs) │
|
||
|
|
│ - GET, POST, PUT │
|
||
|
|
│ - submit, approve, publish │
|
||
|
|
│ - versions │
|
||
|
|
└────────────────────┬────────────────────────────────────┘
|
||
|
|
│
|
||
|
|
▼
|
||
|
|
┌─────────────────────────────────────────────────────────┐
|
||
|
|
│ PostgreSQL (tes_content schema) │
|
||
|
|
│ - drugs (tabla principal) │
|
||
|
|
│ - drug_versions (versionado) │
|
||
|
|
└────────────────────┬────────────────────────────────────┘
|
||
|
|
│
|
||
|
|
▼
|
||
|
|
┌─────────────────────────────────────────────────────────┐
|
||
|
|
│ Content Pack Generator │
|
||
|
|
│ - loadPublishedDrugs() │
|
||
|
|
│ - Incluye en /api/content-pack/latest.json │
|
||
|
|
└─────────────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📊 ESTRUCTURA DE DATOS
|
||
|
|
|
||
|
|
### Tabla: `drugs`
|
||
|
|
|
||
|
|
```sql
|
||
|
|
CREATE TABLE tes_content.drugs (
|
||
|
|
-- Identificación
|
||
|
|
id UUID PRIMARY KEY,
|
||
|
|
slug TEXT UNIQUE NOT NULL,
|
||
|
|
|
||
|
|
-- Información básica
|
||
|
|
generic_name TEXT NOT NULL,
|
||
|
|
trade_name TEXT,
|
||
|
|
|
||
|
|
-- Clasificación
|
||
|
|
category TEXT NOT NULL,
|
||
|
|
line tes_content.drug_line NOT NULL, -- 'first' | 'second'
|
||
|
|
frequency tes_content.drug_frequency NOT NULL, -- 'high' | 'medium' | 'low'
|
||
|
|
|
||
|
|
-- Presentación y dosificación
|
||
|
|
presentation TEXT NOT NULL,
|
||
|
|
adult_dose TEXT NOT NULL,
|
||
|
|
pediatric_dose TEXT, -- Obligatorio si published
|
||
|
|
routes TEXT[] DEFAULT '{}',
|
||
|
|
dilution TEXT,
|
||
|
|
|
||
|
|
-- Indicaciones y contraindicaciones
|
||
|
|
indications TEXT[] DEFAULT '{}',
|
||
|
|
contraindications TEXT[] DEFAULT '{}',
|
||
|
|
side_effects TEXT,
|
||
|
|
antidote TEXT,
|
||
|
|
|
||
|
|
-- Información específica TES
|
||
|
|
notes TEXT[] DEFAULT '{}',
|
||
|
|
critical_points TEXT[] DEFAULT '{}',
|
||
|
|
source TEXT,
|
||
|
|
|
||
|
|
-- Estado y validación
|
||
|
|
status tes_content.content_status NOT NULL DEFAULT 'draft',
|
||
|
|
|
||
|
|
-- Versionado
|
||
|
|
version TEXT NOT NULL DEFAULT '1.0.0',
|
||
|
|
latest_version TEXT NOT NULL DEFAULT '1.0.0',
|
||
|
|
current_version_id UUID,
|
||
|
|
|
||
|
|
-- Auditoría
|
||
|
|
created_by UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
updated_by UUID,
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
published_by UUID,
|
||
|
|
published_at TIMESTAMPTZ,
|
||
|
|
|
||
|
|
-- Metadatos
|
||
|
|
metadata JSONB DEFAULT '{}'
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
### Tabla: `drug_versions`
|
||
|
|
|
||
|
|
```sql
|
||
|
|
CREATE TABLE tes_content.drug_versions (
|
||
|
|
id UUID PRIMARY KEY,
|
||
|
|
drug_id UUID NOT NULL REFERENCES drugs(id),
|
||
|
|
version TEXT NOT NULL,
|
||
|
|
drug_snapshot JSONB NOT NULL,
|
||
|
|
change_summary TEXT NOT NULL,
|
||
|
|
change_details JSONB,
|
||
|
|
change_type TEXT NOT NULL DEFAULT 'patch', -- 'major' | 'minor' | 'patch'
|
||
|
|
is_breaking BOOLEAN DEFAULT false,
|
||
|
|
is_active BOOLEAN NOT NULL DEFAULT false,
|
||
|
|
created_by UUID NOT NULL,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
published_at TIMESTAMPTZ,
|
||
|
|
published_by UUID
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔌 ENDPOINTS API
|
||
|
|
|
||
|
|
### GET /api/drugs
|
||
|
|
|
||
|
|
Lista fármacos con filtros opcionales.
|
||
|
|
|
||
|
|
**Query params:**
|
||
|
|
- `category` - Filtrar por categoría
|
||
|
|
- `line` - Filtrar por línea (`first` | `second`)
|
||
|
|
- `frequency` - Filtrar por frecuencia (`high` | `medium` | `low`)
|
||
|
|
- `status` - Filtrar por estado
|
||
|
|
- `search` - Búsqueda por texto
|
||
|
|
- `page` - Número de página (default: 1)
|
||
|
|
- `limit` - Items por página (default: 50)
|
||
|
|
|
||
|
|
**Respuesta:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"drugs": [...],
|
||
|
|
"pagination": {
|
||
|
|
"page": 1,
|
||
|
|
"limit": 50,
|
||
|
|
"total": 35,
|
||
|
|
"totalPages": 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### GET /api/drugs/:id
|
||
|
|
|
||
|
|
Obtiene un fármaco por ID o slug.
|
||
|
|
|
||
|
|
**Respuesta:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": "...",
|
||
|
|
"slug": "adrenalina",
|
||
|
|
"generic_name": "Adrenalina",
|
||
|
|
"trade_name": "Adrenalina 1mg/1ml",
|
||
|
|
...
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### POST /api/drugs
|
||
|
|
|
||
|
|
Crea un nuevo fármaco (draft).
|
||
|
|
|
||
|
|
**Requiere:** `content:create` permission
|
||
|
|
|
||
|
|
**Body:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"generic_name": "Adrenalina",
|
||
|
|
"category": "cardiovascular",
|
||
|
|
"line": "first",
|
||
|
|
"frequency": "high",
|
||
|
|
"presentation": "1mg/1ml ampolla",
|
||
|
|
"adult_dose": "1mg IV/IO cada 3-5 min",
|
||
|
|
...
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### PUT /api/drugs/:id
|
||
|
|
|
||
|
|
Actualiza un fármaco existente.
|
||
|
|
|
||
|
|
**Requiere:** `content:edit` permission
|
||
|
|
|
||
|
|
**Body:** Mismo formato que POST, solo campos a actualizar.
|
||
|
|
|
||
|
|
### POST /api/drugs/:id/submit
|
||
|
|
|
||
|
|
Envía un fármaco a revisión (draft → in_review).
|
||
|
|
|
||
|
|
**Requiere:** `content:submit` permission
|
||
|
|
|
||
|
|
### POST /api/drugs/:id/approve
|
||
|
|
|
||
|
|
Aprueba un fármaco (in_review → approved).
|
||
|
|
|
||
|
|
**Requiere:** `validation:approve` permission
|
||
|
|
|
||
|
|
**Body (opcional):**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"notes": "Comentarios de aprobación"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### POST /api/drugs/:id/publish
|
||
|
|
|
||
|
|
Publica un fármaco (approved → published).
|
||
|
|
|
||
|
|
**Requiere:** `content:publish` permission
|
||
|
|
|
||
|
|
**Validación:** `pediatric_dose` debe estar presente.
|
||
|
|
|
||
|
|
### GET /api/drugs/:id/versions
|
||
|
|
|
||
|
|
Obtiene historial de versiones de un fármaco.
|
||
|
|
|
||
|
|
**Requiere:** Autenticación
|
||
|
|
|
||
|
|
**Respuesta:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"versions": [
|
||
|
|
{
|
||
|
|
"id": "...",
|
||
|
|
"version": "1.2.3",
|
||
|
|
"change_summary": "...",
|
||
|
|
"change_type": "minor",
|
||
|
|
"is_active": true,
|
||
|
|
"created_at": "..."
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎨 PANEL ADMIN
|
||
|
|
|
||
|
|
### Ruta: `/drugs`
|
||
|
|
|
||
|
|
**DrugManagerPage** - Lista de fármacos con:
|
||
|
|
- Filtros: categoría, línea, frecuencia, estado, búsqueda
|
||
|
|
- Tabla con información clave
|
||
|
|
- Acciones: Ver, Editar, Enviar a revisión
|
||
|
|
- Paginación
|
||
|
|
|
||
|
|
### Ruta: `/drugs/new` o `/drugs/:id/edit`
|
||
|
|
|
||
|
|
**DrugEditorPage** - Editor completo con:
|
||
|
|
- Información básica (nombre genérico, comercial, categoría, línea, frecuencia)
|
||
|
|
- Presentación y dosificación (adulto, pediátrica, vías, dilución)
|
||
|
|
- Indicaciones y contraindicaciones (arrays editables)
|
||
|
|
- Efectos adversos y antídoto
|
||
|
|
- Notas y puntos críticos TES (arrays editables)
|
||
|
|
- Fuente
|
||
|
|
- Botones de acción según estado y permisos
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📦 CONTENT PACK
|
||
|
|
|
||
|
|
Los fármacos publicados se incluyen automáticamente en el Content Pack:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"metadata": {
|
||
|
|
"version": "1.0.0",
|
||
|
|
"generated_at": "...",
|
||
|
|
"hash": "sha256:..."
|
||
|
|
},
|
||
|
|
"content": {
|
||
|
|
"drugs": [
|
||
|
|
{
|
||
|
|
"id": "...",
|
||
|
|
"slug": "adrenalina",
|
||
|
|
"genericName": "Adrenalina",
|
||
|
|
"tradeName": "Adrenalina 1mg/1ml",
|
||
|
|
"category": "cardiovascular",
|
||
|
|
"line": "first",
|
||
|
|
"frequency": "high",
|
||
|
|
"presentation": "1mg/1ml ampolla",
|
||
|
|
"adultDose": "1mg IV/IO cada 3-5 min",
|
||
|
|
"pediatricDose": "0.01mg/kg IV/IO",
|
||
|
|
"routes": ["IV", "IO", "IM"],
|
||
|
|
...
|
||
|
|
}
|
||
|
|
],
|
||
|
|
...
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔄 WORKFLOW DE VALIDACIÓN
|
||
|
|
|
||
|
|
```
|
||
|
|
draft → [submit] → in_review → [approve] → approved → [publish] → published
|
||
|
|
↓ ↓
|
||
|
|
archived (en Content Pack)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Estados:**
|
||
|
|
- `draft` - Borrador (editable por creador)
|
||
|
|
- `in_review` - En revisión (esperando aprobación)
|
||
|
|
- `approved` - Aprobado (listo para publicar)
|
||
|
|
- `published` - Publicado (incluido en Content Pack)
|
||
|
|
- `archived` - Archivado (no visible)
|
||
|
|
|
||
|
|
**Transiciones:**
|
||
|
|
- `draft` → `in_review`: Requiere `content:submit`
|
||
|
|
- `in_review` → `approved`: Requiere `validation:approve`
|
||
|
|
- `approved` → `published`: Requiere `content:publish` + `pediatric_dose`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📋 SCRIPT DE SEED
|
||
|
|
|
||
|
|
### Ejecutar seed
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd backend
|
||
|
|
npm run seed:drugs
|
||
|
|
```
|
||
|
|
|
||
|
|
### Fármacos incluidos
|
||
|
|
|
||
|
|
**Primera Línea (15 fármacos):**
|
||
|
|
1. Adrenalina ✅ (published)
|
||
|
|
2. Amiodarona ✅ (published)
|
||
|
|
3. Atropina ✅ (published)
|
||
|
|
4. Suero Fisiológico 0.9% (draft)
|
||
|
|
5. Ringer Lactato (draft)
|
||
|
|
6. Oxígeno ✅ (published)
|
||
|
|
7. Salbutamol (draft)
|
||
|
|
8. Glucosa 50% (draft)
|
||
|
|
9. Diazepam (draft)
|
||
|
|
10. Midazolam ✅ (published)
|
||
|
|
11. Morfina (draft)
|
||
|
|
12. Paracetamol (draft)
|
||
|
|
13. AAS (draft)
|
||
|
|
14. Naloxona (draft)
|
||
|
|
15. Flumazenil (draft)
|
||
|
|
|
||
|
|
**Segunda Línea (20 fármacos):**
|
||
|
|
Todos en estado `draft` con "PENDIENTE VALIDACIÓN CLÍNICA" en campos faltantes.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ✅ VALIDACIONES
|
||
|
|
|
||
|
|
### Backend
|
||
|
|
|
||
|
|
- `generic_name` obligatorio
|
||
|
|
- `category` obligatorio
|
||
|
|
- `line` debe ser `first` o `second`
|
||
|
|
- `frequency` debe ser `high`, `medium` o `low`
|
||
|
|
- `presentation` obligatorio
|
||
|
|
- `adult_dose` obligatorio
|
||
|
|
- `pediatric_dose` obligatorio si `status = published`
|
||
|
|
- Arrays normalizados (routes, indications, etc.)
|
||
|
|
- Versión semántica validada
|
||
|
|
|
||
|
|
### Frontend
|
||
|
|
|
||
|
|
- Validación de campos requeridos
|
||
|
|
- Advertencia si `pediatric_dose` falta y se intenta publicar
|
||
|
|
- Validación de arrays antes de guardar
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔐 PERMISOS
|
||
|
|
|
||
|
|
| Acción | Permiso Requerido |
|
||
|
|
|--------|-------------------|
|
||
|
|
| Ver fármacos | Ninguno (público) |
|
||
|
|
| Crear fármaco | `content:create` |
|
||
|
|
| Editar fármaco | `content:edit` |
|
||
|
|
| Enviar a revisión | `content:submit` |
|
||
|
|
| Aprobar | `validation:approve` |
|
||
|
|
| Publicar | `content:publish` |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🚀 INSTALACIÓN Y USO
|
||
|
|
|
||
|
|
### 1. Ejecutar migración
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd backend
|
||
|
|
npm run migrate:drugs
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Ejecutar seed
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm run seed:drugs
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Verificar
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Probar endpoint
|
||
|
|
curl http://localhost:3000/api/drugs
|
||
|
|
|
||
|
|
# Probar panel admin
|
||
|
|
# Abrir http://localhost:5174/drugs
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📝 NOTAS IMPORTANTES
|
||
|
|
|
||
|
|
1. **No modifica código existente** - Todo es aditivo
|
||
|
|
2. **Solo capa de referencia** - No operativa ni formativa
|
||
|
|
3. **Self-hosted** - Todo en PostgreSQL
|
||
|
|
4. **Placeholders claros** - "PENDIENTE VALIDACIÓN CLÍNICA" donde falta información
|
||
|
|
5. **Versionado automático** - Cada cambio crea nueva versión
|
||
|
|
6. **Auditoría completa** - Todas las acciones se registran en `audit_logs`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔄 PRÓXIMOS PASOS SUGERIDOS
|
||
|
|
|
||
|
|
1. **Completar información faltante** - Llenar los 30 fármacos con "PENDIENTE VALIDACIÓN CLÍNICA"
|
||
|
|
2. **Validación clínica** - Revisar y aprobar fármacos desde el panel
|
||
|
|
3. **Integración en app PWA** - Consumir drugs desde Content Pack
|
||
|
|
4. **Búsqueda avanzada** - Mejorar búsqueda en panel admin
|
||
|
|
5. **Exportación** - Exportar vademécum a PDF/Excel
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Última actualización:** 2025-01-07
|
||
|
|
**Estado:** ✅ IMPLEMENTACIÓN COMPLETA
|
||
|
|
|