codigo0/docs/ARQUITECTURA_SERVIDOR_CONTENIDO.md

496 lines
17 KiB
Markdown

# 🏗️ ARQUITECTURA SERVIDOR DE CONTENIDO - TES
**Versión:** 1.0.0
**Fecha:** 2025-01-06
**Estado:** Diseño Técnico - Sin Implementación
---
## 🎯 PRINCIPIOS FUNDAMENTALES
1. **Servidor Propio**
- ✅ PostgreSQL en nuestro servidor
- ✅ API REST de solo lectura para app
- ✅ Panel admin separado (solo editores)
- ❌ NO Supabase
- ❌ NO servicios externos
- ❌ NO CMS externo
2. **App PWA (Solo Consumo)**
- ✅ Consume Content Pack JSON
- ✅ Funciona offline-first
- ✅ Cache local (IndexedDB)
- ❌ NO edita contenido
- ❌ NO tiene panel admin
3. **Separación Clara**
- Servidor → Genera Content Pack
- App → Consume Content Pack
- Panel Admin → Edita en servidor
---
## 📐 ARQUITECTURA GENERAL
```
┌─────────────────────────────────────────────────────────┐
│ SERVIDOR PROPIO │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ PostgreSQL Database │ │
│ │ ├── content_items │ │
│ │ ├── media_resources │ │
│ │ ├── associations │ │
│ │ ├── versions │ │
│ │ └── audit_logs │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ │ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ API REST (Node.js + Express) │ │
│ │ ├── GET /api/content/pack/latest │ │
│ │ ├── GET /api/content/pack/:version │ │
│ │ ├── GET /api/content/protocol/:id │ │
│ │ ├── GET /api/content/guide/:id │ │
│ │ └── GET /api/health │ │
│ │ (SOLO LECTURA - Sin autenticación para app) │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ │ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Panel Admin (React - Puerto 5174) │ │
│ │ ├── Editor de contenido │ │
│ │ ├── Gestor de recursos │ │
│ │ ├── Validación clínica │ │
│ │ └── Exportación de packs │ │
│ │ (REQUIERE AUTENTICACIÓN) │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ │ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Generador Content Pack │ │
│ │ ├── Lee de PostgreSQL │ │
│ │ ├── Genera JSON optimizado │ │
│ │ ├── Calcula hash SHA-256 │ │
│ │ └── Guarda en /packs/ │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
│ (Content Pack JSON)
┌─────────────────────────────────────────────────────────┐
│ APP PWA (Frontend) │
├─────────────────────────────────────────────────────────┤
│ ┌──────────────────────────────────────────────────┐ │
│ │ Service Worker │ │
│ │ ├── Descarga pack al iniciar │ │
│ │ ├── Cache en IndexedDB │ │
│ │ └── Funciona 100% offline │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Content Adapter │ │
│ │ ├── Lee de cache local │ │
│ │ ├── Fallback a procedures.ts si no hay pack │ │
│ │ └── Sin modificar código existente │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
```
---
## 🗄️ BASE DE DATOS (PostgreSQL)
### Esquema: `tes_content`
**Justificación:**
- Schema dedicado para contenido
- Separado de otros datos del sistema
- Fácil backup y migración
### Tablas Principales
Ver `docs/SERVER_DATABASE_SCHEMA.sql` (se creará a continuación)
---
## 🔌 API REST (Solo Lectura)
### Endpoints Públicos (Sin Autenticación)
#### 1. Health Check
```
GET /api/health
```
**Respuesta:**
```json
{
"status": "ok",
"timestamp": "2025-01-06T12:00:00Z",
"database": "connected",
"latest_pack_version": "1.0.0"
}
```
#### 2. Content Pack Latest
```
GET /api/content/pack/latest
```
**Respuesta:** Content Pack JSON completo (ver especificación)
**Headers:**
- `If-None-Match: <hash>` - Para validar si hay cambios
- `ETag: <hash>` - Hash del pack en respuesta
#### 3. Content Pack por Versión
```
GET /api/content/pack/:version
```
**Ejemplo:** `GET /api/content/pack/1.0.0`
#### 4. Protocolo Individual
```
GET /api/content/protocol/:slug
```
**Ejemplo:** `GET /api/content/protocol/rcp-adulto-svb`
**Respuesta:**
```json
{
"id": "...",
"type": "protocol",
"slug": "rcp-adulto-svb",
"title": "RCP Adulto - Soporte Vital Básico",
"content": { ... },
"resources": {
"images": [...],
"videos": [...]
}
}
```
#### 5. Guía Individual
```
GET /api/content/guide/:slug
```
#### 6. Recurso Multimedia
```
GET /api/content/media/:id
```
**Respuesta:** URL del recurso o redirección a archivo
---
### Endpoints Admin (Con Autenticación)
Ver sección "Panel Admin" más abajo.
---
## 📦 CONTENT PACK JSON
### Estructura (Optimizada para Offline)
```json
{
"metadata": {
"version": "1.0.0",
"generated_at": "2025-01-06T12:00:00Z",
"hash": "sha256:abc123...",
"total_items": 45,
"total_resources": 120,
"size_bytes": 5242880
},
"content": {
"protocols": [...],
"guides": [...],
"manuals": [...],
"drugs": [...],
"checklists": [...]
},
"media": {
"resources": [...],
"associations": [...]
},
"links": {
"protocol_to_guide": [...],
"guide_to_protocol": [...],
"manual_to_protocols": [...]
}
}
```
**Características:**
- ✅ Solo contenido `published`
- ✅ Solo última versión
- ✅ Recursos asociados incluidos
- ✅ Enlaces bidireccionales pre-calculados
- ✅ Hash SHA-256 para verificación
- ✅ Tamaño optimizado (< 10MB recomendado)
**Ubicación en Servidor:**
```
/packs/
├── pack-v1.0.0.json
├── pack-v1.1.0.json
└── pack-latest.json (symlink)
```
---
## 🎛️ PANEL ADMIN (Conceptual)
### Arquitectura
```
┌─────────────────────────────────────────┐
│ Panel Admin (React - Puerto 5174) │
├─────────────────────────────────────────┤
│ ┌───────────────────────────────────┐ │
│ │ Auth (JWT) │ │
│ │ - Login en servidor │ │
│ │ - Token almacenado localmente │ │
│ └───────────────────────────────────┘ │
│ ┌───────────────────────────────────┐ │
│ │ Editor de Protocolo │ │
│ │ - Tabs: Básico, Pasos, Checklist │ │
│ │ - Preview "Modo TES" │ │
│ │ - Guarda en servidor via API │ │
│ └───────────────────────────────────┘ │
│ ┌───────────────────────────────────┐ │
│ │ Gestor de Recursos │ │
│ │ - Upload a servidor │ │
│ │ - Asociar a contenido │ │
│ └───────────────────────────────────┘ │
│ ┌───────────────────────────────────┐ │
│ │ Generador de Pack │ │
│ │ - Botón "Generar Pack" │ │
│ │ - Seleccionar versión │ │
│ │ - Descargar JSON │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
│ (API REST con Auth)
┌─────────────────────────────────────────┐
│ API Admin (Node.js + Express) │
│ - POST /api/admin/content │
│ - PUT /api/admin/content/:id │
│ - POST /api/admin/media │
│ - POST /api/admin/pack/generate │
└─────────────────────────────────────────┘
```
### Endpoints Admin
#### Autenticación
```
POST /api/admin/auth/login
POST /api/admin/auth/logout
GET /api/admin/auth/me
```
#### Contenido
```
GET /api/admin/content # Lista con filtros
GET /api/admin/content/:id # Detalle
POST /api/admin/content # Crear
PUT /api/admin/content/:id # Actualizar
DELETE /api/admin/content/:id # Eliminar (soft delete)
POST /api/admin/content/:id/validate # Solicitar validación
POST /api/admin/content/:id/publish # Publicar
```
#### Recursos
```
GET /api/admin/media # Lista
POST /api/admin/media/upload # Upload archivo
PUT /api/admin/media/:id # Actualizar metadatos
DELETE /api/admin/media/:id # Eliminar
POST /api/admin/media/:id/associate # Asociar a contenido
```
#### Content Pack
```
POST /api/admin/pack/generate # Generar nuevo pack
GET /api/admin/pack/versions # Lista de versiones
GET /api/admin/pack/:version # Descargar pack específico
```
---
## 🔒 SEGURIDAD
### API Pública (App)
- Sin autenticación (solo lectura)
- Rate limiting (100 req/min por IP)
- CORS configurado (solo dominios permitidos)
- Validación de inputs
### API Admin
- Autenticación JWT obligatoria
- RBAC (Roles: editor, validador, admin)
- Rate limiting (50 req/min por usuario)
- Validación de permisos por endpoint
- Audit log de todas las acciones
---
## 📁 ESTRUCTURA DE DIRECTORIOS (Servidor)
```
server/
├── config/
│ ├── database.js # Config PostgreSQL
│ └── storage.js # Config almacenamiento archivos
├── database/
│ ├── migrations/
│ │ ├── 001_create_schema.sql
│ │ └── 002_create_tables.sql
│ └── seeds/
│ └── initial_data.sql
├── src/
│ ├── api/
│ │ ├── public/ # Endpoints públicos (app)
│ │ │ ├── health.js
│ │ │ ├── content-pack.js
│ │ │ └── content.js
│ │ └── admin/ # Endpoints admin
│ │ ├── auth.js
│ │ ├── content.js
│ │ ├── media.js
│ │ └── pack.js
│ ├── services/
│ │ ├── content-service.js
│ │ ├── media-service.js
│ │ └── pack-generator.js # Generador de Content Pack
│ ├── middleware/
│ │ ├── auth.js
│ │ ├── rbac.js
│ │ └── rate-limit.js
│ └── utils/
│ ├── validation.js
│ └── hash.js
├── storage/
│ ├── media/
│ │ ├── images/
│ │ └── videos/
│ └── packs/
│ ├── pack-v1.0.0.json
│ └── pack-latest.json
├── admin-panel/ # Panel admin (React)
│ └── (ya existe)
└── index.js # Servidor Express principal
```
---
## 🔄 FLUJO DE TRABAJO
### 1. Editor Crea Contenido
```
Editor → Panel Admin → POST /api/admin/content
→ Guarda en PostgreSQL (status: 'draft')
```
### 2. Validador Revisa
```
Validador → Panel Admin → POST /api/admin/content/:id/validate
→ Actualiza status: 'approved'
```
### 3. Admin Publica
```
Admin → Panel Admin → POST /api/admin/content/:id/publish
→ Actualiza status: 'published'
```
### 4. Generar Content Pack
```
Admin → Panel Admin → POST /api/admin/pack/generate
→ Genera JSON desde PostgreSQL
→ Calcula hash
→ Guarda en /storage/packs/
→ Crea symlink pack-latest.json
```
### 5. App Consume
```
App → GET /api/content/pack/latest
→ Descarga JSON
→ Cache en IndexedDB
→ Funciona offline
```
---
## 📊 MODELO DE DATOS (Resumen)
Ver `docs/SERVER_DATABASE_SCHEMA.sql` para detalles completos.
**Tablas:**
- `content_items` - Contenido principal
- `media_resources` - Recursos multimedia
- `content_resource_associations` - Asociaciones
- `content_versions` - Historial de versiones
- `audit_logs` - Auditoría
- `users` - Usuarios del panel admin
---
## ✅ CHECKLIST DE IMPLEMENTACIÓN
### Fase 1: Base de Datos
- [ ] Crear schema `tes_content`
- [ ] Crear tablas (content_items, media_resources, etc.)
- [ ] Crear índices
- [ ] Crear triggers
- [ ] Migrar contenido inicial
### Fase 2: API Pública
- [ ] Endpoint `/api/health`
- [ ] Endpoint `/api/content/pack/latest`
- [ ] Endpoint `/api/content/pack/:version`
- [ ] Endpoint `/api/content/protocol/:slug`
- [ ] Endpoint `/api/content/guide/:slug`
- [ ] Rate limiting
- [ ] CORS configurado
### Fase 3: Generador de Pack
- [ ] Servicio `pack-generator.js`
- [ ] Lectura desde PostgreSQL
- [ ] Generación de JSON
- [ ] Cálculo de hash SHA-256
- [ ] Guardado en `/storage/packs/`
- [ ] Symlink `pack-latest.json`
### Fase 4: API Admin
- [ ] Autenticación JWT
- [ ] RBAC middleware
- [ ] Endpoints CRUD contenido
- [ ] Endpoints gestión recursos
- [ ] Endpoint generación pack
- [ ] Audit logging
### Fase 5: Panel Admin
- [ ] Editor de protocolos
- [ ] Editor de guías
- [ ] Gestor de recursos
- [ ] Generador de pack (UI)
- [ ] Dashboard de estado
### Fase 6: Integración App
- [ ] ContentAdapter en app
- [ ] Descarga de pack al iniciar
- [ ] Cache en IndexedDB
- [ ] Fallback a procedures.ts
- [ ] Testing offline
---
**Fin del Documento**