# πŸ—οΈ 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: ` - Para validar si hay cambios - `ETag: ` - 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**