17 KiB
17 KiB
🏗️ ARQUITECTURA SERVIDOR DE CONTENIDO - TES
Versión: 1.0.0
Fecha: 2025-01-06
Estado: Diseño Técnico - Sin Implementación
🎯 PRINCIPIOS FUNDAMENTALES
-
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
-
App PWA (Solo Consumo)
- ✅ Consume Content Pack JSON
- ✅ Funciona offline-first
- ✅ Cache local (IndexedDB)
- ❌ NO edita contenido
- ❌ NO tiene panel admin
-
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:
{
"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 cambiosETag: <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:
{
"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)
{
"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 principalmedia_resources- Recursos multimediacontent_resource_associations- Asociacionescontent_versions- Historial de versionesaudit_logs- Auditoríausers- 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