402 lines
11 KiB
Markdown
402 lines
11 KiB
Markdown
|
|
# Arquitectura del Sistema - EMERGES TES
|
||
|
|
|
||
|
|
**Arquitectura actual, componentes principales y entidades del dominio.**
|
||
|
|
|
||
|
|
**Última actualización:** 2025-02-02
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🏗️ Arquitectura General
|
||
|
|
|
||
|
|
### Estructura del Proyecto
|
||
|
|
|
||
|
|
```
|
||
|
|
guia-tes/
|
||
|
|
├── src/ # Frontend (React + TypeScript)
|
||
|
|
├── backend/ # Backend (Express + PostgreSQL)
|
||
|
|
├── admin-panel/ # Panel de administración (React)
|
||
|
|
├── public/ # Assets estáticos, manual
|
||
|
|
├── docs/ # Documentación
|
||
|
|
└── scripts/ # Scripts de utilidad
|
||
|
|
```
|
||
|
|
|
||
|
|
### Separación Frontend / Backend
|
||
|
|
|
||
|
|
- **Frontend:** Aplicación PWA independiente, funciona offline
|
||
|
|
- **Backend:** API REST para gestión de contenido (admin)
|
||
|
|
- **Admin Panel:** Interfaz de administración separada
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎯 Arquitectura Backend (Clean Architecture)
|
||
|
|
|
||
|
|
### Estructura de Capas
|
||
|
|
|
||
|
|
```
|
||
|
|
backend/src/
|
||
|
|
├── domain/ # Domain Layer (NO depende de nadie)
|
||
|
|
│ ├── entities/ # Entidades de dominio
|
||
|
|
│ ├── value-objects/ # Value Objects
|
||
|
|
│ └── repositories/ # Interfaces de repositorios
|
||
|
|
├── application/ # Application Layer (depende de Domain)
|
||
|
|
│ └── services/ # Servicios de aplicación
|
||
|
|
├── infrastructure/ # Infrastructure Layer (depende de Domain + Application)
|
||
|
|
│ ├── repositories/ # Implementaciones de repositorios
|
||
|
|
│ ├── mappers/ # Mappers Domain ↔ Persistence
|
||
|
|
│ └── database/ # Configuración BD
|
||
|
|
├── presentation/ # Presentation Layer (depende de Application + Domain)
|
||
|
|
│ └── routes/ # Rutas Express (API endpoints)
|
||
|
|
├── shared/ # Código compartido
|
||
|
|
│ ├── schemas/ # Schemas Zod
|
||
|
|
│ └── errors/ # Errores personalizados
|
||
|
|
└── middleware/ # Middleware Express
|
||
|
|
```
|
||
|
|
|
||
|
|
### Reglas de Dependencias
|
||
|
|
|
||
|
|
```
|
||
|
|
Domain Layer
|
||
|
|
↑
|
||
|
|
Application Layer
|
||
|
|
↑
|
||
|
|
Infrastructure Layer
|
||
|
|
↑
|
||
|
|
Presentation Layer
|
||
|
|
```
|
||
|
|
|
||
|
|
**Regla:** Las dependencias apuntan siempre hacia adentro (hacia el Dominio).
|
||
|
|
|
||
|
|
- ✅ **Domain:** NO depende de nadie
|
||
|
|
- ✅ **Application:** Solo depende de Domain
|
||
|
|
- ✅ **Infrastructure:** Depende de Domain y Application
|
||
|
|
- ✅ **Presentation:** Depende de Application y Domain
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📦 Componentes Principales
|
||
|
|
|
||
|
|
### 1. Domain Layer
|
||
|
|
|
||
|
|
#### Entidades de Dominio
|
||
|
|
|
||
|
|
**ContentItem** (`domain/entities/ContentItem.ts`)
|
||
|
|
- Protocolos, guías, manuales, checklists
|
||
|
|
- Estados: `draft`, `in_review`, `approved`, `published`, `archived`
|
||
|
|
- Ciclo de vida: Validación médica (submit → approve/reject → publish)
|
||
|
|
|
||
|
|
**Drug** (`domain/entities/Drug.ts`)
|
||
|
|
- Fármacos con especificaciones técnicas
|
||
|
|
- Categorías: cardiovascular, respiratorio, neurológico, etc.
|
||
|
|
- Dosis adulto/pediátrica, vías de administración
|
||
|
|
|
||
|
|
**GlossaryTerm** (`domain/entities/GlossaryTerm.ts`)
|
||
|
|
- Términos médicos del glosario
|
||
|
|
- Categorías: pharmaceutical, anatomical, clinical, procedural
|
||
|
|
- Relaciones con otros términos
|
||
|
|
|
||
|
|
**MediaResource** (`domain/entities/MediaResource.ts`)
|
||
|
|
- Imágenes, vídeos, documentos
|
||
|
|
- Asociación a bloques/capítulos del manual
|
||
|
|
- Metadatos (título, descripción, alt text)
|
||
|
|
|
||
|
|
**MedicalReview** (`domain/entities/MedicalReview.ts`)
|
||
|
|
- Revisiones médicas de contenido
|
||
|
|
- Estados: `pending`, `approved`, `rejected`
|
||
|
|
- Comentarios y validación clínica
|
||
|
|
|
||
|
|
#### Value Objects
|
||
|
|
|
||
|
|
**ContentStatus** (`domain/value-objects/ContentStatus.ts`)
|
||
|
|
- Estados válidos y transiciones permitidas
|
||
|
|
- Métodos: `canTransitionTo()`, `fromString()`
|
||
|
|
|
||
|
|
**ContentPriority** (`domain/value-objects/ContentPriority.ts`)
|
||
|
|
- Prioridades: `critica`, `alta`, `media`, `baja`
|
||
|
|
|
||
|
|
#### Repository Interfaces
|
||
|
|
|
||
|
|
- `IContentRepository` - Operaciones CRUD de contenido
|
||
|
|
- `IDrugRepository` - Operaciones CRUD de fármacos
|
||
|
|
- `IGlossaryRepository` - Operaciones CRUD de glosario
|
||
|
|
- `IValidationRepository` - Operaciones de validación médica
|
||
|
|
- `IMediaRepository` - Operaciones CRUD de medios
|
||
|
|
|
||
|
|
### 2. Application Layer
|
||
|
|
|
||
|
|
#### Servicios de Aplicación
|
||
|
|
|
||
|
|
**ContentService** (`application/services/ContentService.ts`)
|
||
|
|
- Lógica de negocio para contenido
|
||
|
|
- Validaciones complejas (unicidad, dependencias)
|
||
|
|
- Orquestación de casos de uso
|
||
|
|
|
||
|
|
**GlossaryService** (`application/services/GlossaryService.ts`)
|
||
|
|
- Lógica de negocio para glosario
|
||
|
|
- Búsqueda y filtrado
|
||
|
|
- Validaciones de términos
|
||
|
|
|
||
|
|
**ValidationService** (`application/services/ValidationService.ts`)
|
||
|
|
- Workflow de validación médica
|
||
|
|
- Transiciones de estado usando `ContentStatus`
|
||
|
|
- Registro de auditoría
|
||
|
|
|
||
|
|
**StatsService** (`application/services/StatsService.ts`)
|
||
|
|
- Estadísticas de contenido, validación, medios
|
||
|
|
- Caché de estadísticas
|
||
|
|
|
||
|
|
**DrugService** (`application/services/DrugService.ts`)
|
||
|
|
- Lógica de negocio para fármacos
|
||
|
|
- Validaciones y búsqueda
|
||
|
|
|
||
|
|
### 3. Infrastructure Layer
|
||
|
|
|
||
|
|
#### Repositorios (Implementaciones)
|
||
|
|
|
||
|
|
- `ContentRepository` - PostgreSQL para contenido
|
||
|
|
- `DrugRepository` - PostgreSQL para fármacos
|
||
|
|
- `GlossaryRepository` - PostgreSQL para glosario
|
||
|
|
- `ValidationRepository` - PostgreSQL para validación
|
||
|
|
- `MediaRepository` - PostgreSQL para medios
|
||
|
|
|
||
|
|
#### Mappers
|
||
|
|
|
||
|
|
- `ContentItemMapper` - Domain ↔ Persistence
|
||
|
|
- `DrugMapper` - Domain ↔ Persistence
|
||
|
|
- `GlossaryTermMapper` - Domain ↔ Persistence
|
||
|
|
|
||
|
|
**Regla:** Los mappers validan con Zod antes de convertir a dominio.
|
||
|
|
|
||
|
|
### 4. Presentation Layer
|
||
|
|
|
||
|
|
#### Rutas API (`presentation/routes/`)
|
||
|
|
|
||
|
|
- `content.ts` - CRUD de contenido (`/api/content/*`)
|
||
|
|
- `drugs.ts` - CRUD de fármacos (`/api/drugs/*`)
|
||
|
|
- `glossary.ts` - CRUD de glosario (`/api/glossary/*`)
|
||
|
|
- `validation.ts` - Validación médica (`/api/validation/*`)
|
||
|
|
- `media.ts` - Gestión de medios (`/api/media/*`)
|
||
|
|
- `stats.ts` - Estadísticas (`/api/stats/*`)
|
||
|
|
|
||
|
|
#### Middleware
|
||
|
|
|
||
|
|
- `auth.ts` - Autenticación JWT
|
||
|
|
- `validate.ts` - Validación de requests con Zod
|
||
|
|
- `rate-limit.ts` - Rate limiting
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎨 Arquitectura Frontend
|
||
|
|
|
||
|
|
### Estructura
|
||
|
|
|
||
|
|
```
|
||
|
|
src/
|
||
|
|
├── components/ # Componentes React
|
||
|
|
│ ├── content/ # Componentes de contenido
|
||
|
|
│ ├── drugs/ # Componentes de fármacos
|
||
|
|
│ ├── guide/ # Componentes de guías
|
||
|
|
│ ├── interactive/ # Componentes interactivos
|
||
|
|
│ └── ui/ # Componentes UI (shadcn/ui)
|
||
|
|
├── pages/ # Páginas/rutas
|
||
|
|
├── hooks/ # Hooks personalizados
|
||
|
|
├── services/ # Servicios (adaptadores, búsqueda)
|
||
|
|
├── data/ # Datos estáticos (protocolos, fármacos)
|
||
|
|
├── utils/ # Utilidades
|
||
|
|
└── types/ # Tipos TypeScript
|
||
|
|
```
|
||
|
|
|
||
|
|
### Patrones
|
||
|
|
|
||
|
|
- **Arquitectura funcional React** (no Clean Architecture estricta)
|
||
|
|
- **Componentes funcionales** con hooks
|
||
|
|
- **Datos estáticos embebidos** (offline-first)
|
||
|
|
- **Service Worker** para caché agresivo
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🗄️ Base de Datos
|
||
|
|
|
||
|
|
### PostgreSQL
|
||
|
|
|
||
|
|
**Esquema:** `tes_content`
|
||
|
|
|
||
|
|
**Tablas principales:**
|
||
|
|
- `content_items` - Protocolos, guías, manuales
|
||
|
|
- `drugs` - Fármacos
|
||
|
|
- `glossary_terms` - Términos del glosario
|
||
|
|
- `media_resources` - Medios audiovisuales
|
||
|
|
- `audit_logs` - Logs de auditoría
|
||
|
|
- `users` - Usuarios (admin)
|
||
|
|
- `content_versions` - Versiones de contenido
|
||
|
|
- `content_resource_associations` - Asociaciones contenido-medios
|
||
|
|
|
||
|
|
**Migraciones:** `backend/database/migrations/`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔄 Flujos Principales
|
||
|
|
|
||
|
|
### 1. Workflow de Validación Médica
|
||
|
|
|
||
|
|
```
|
||
|
|
ContentItem (draft)
|
||
|
|
↓ submit
|
||
|
|
ContentItem (in_review)
|
||
|
|
↓ approve/reject
|
||
|
|
ContentItem (approved/draft)
|
||
|
|
↓ publish (si approved)
|
||
|
|
ContentItem (published)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Implementación:**
|
||
|
|
- `ValidationService` orquesta transiciones
|
||
|
|
- `ContentStatus` valida transiciones permitidas
|
||
|
|
- `ValidationRepository` persiste cambios
|
||
|
|
- `audit_logs` registra acciones
|
||
|
|
|
||
|
|
### 2. Gestión de Contenido
|
||
|
|
|
||
|
|
```
|
||
|
|
Admin crea/edita ContentItem
|
||
|
|
↓
|
||
|
|
ContentService valida
|
||
|
|
↓
|
||
|
|
ContentRepository persiste
|
||
|
|
↓
|
||
|
|
Mapper convierte Domain ↔ Persistence
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Búsqueda y Filtrado
|
||
|
|
|
||
|
|
```
|
||
|
|
Frontend → API endpoint
|
||
|
|
↓
|
||
|
|
Service aplica lógica de negocio
|
||
|
|
↓
|
||
|
|
Repository consulta PostgreSQL
|
||
|
|
↓
|
||
|
|
Mapper convierte a Domain
|
||
|
|
↓
|
||
|
|
Service retorna DTO
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔐 Seguridad
|
||
|
|
|
||
|
|
### Autenticación
|
||
|
|
|
||
|
|
- **JWT** para autenticación de usuarios admin
|
||
|
|
- **Roles:** `admin`, `reviewer`, `validator`
|
||
|
|
- **Middleware:** `authenticate`, `requirePermission`
|
||
|
|
|
||
|
|
### Validación
|
||
|
|
|
||
|
|
- **Zod** en todos los puntos de entrada (API, forms)
|
||
|
|
- **Validación de tipos** en runtime
|
||
|
|
- **Sanitización** de inputs
|
||
|
|
|
||
|
|
### Rate Limiting
|
||
|
|
|
||
|
|
- **express-rate-limit** en endpoints públicos
|
||
|
|
- **Límites** configurables por endpoint
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🧪 Testing
|
||
|
|
|
||
|
|
### Backend
|
||
|
|
|
||
|
|
- **Tests unitarios:** Servicios con repos mockeados
|
||
|
|
- **Tests integración:** API con `supertest`
|
||
|
|
- **Cobertura objetivo:** 80%+
|
||
|
|
|
||
|
|
**Tests:**
|
||
|
|
- `backend/src/application/services/__tests__/`
|
||
|
|
- `backend/src/__tests__/api.integration.test.ts`
|
||
|
|
|
||
|
|
### Frontend
|
||
|
|
|
||
|
|
- **Tests unitarios:** Componentes, hooks, utils
|
||
|
|
- **Vitest** como framework de testing
|
||
|
|
- **Cobertura objetivo:** 80%
|
||
|
|
|
||
|
|
**Tests:**
|
||
|
|
- `src/**/*.test.ts`, `src/**/*.test.tsx`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📊 Entidades con Ciclo de Vida
|
||
|
|
|
||
|
|
### ContentItem
|
||
|
|
|
||
|
|
**Estados:** `draft` → `in_review` → `approved` / `published` → `archived`
|
||
|
|
|
||
|
|
**Transiciones:**
|
||
|
|
- `draft` → `in_review` (submit)
|
||
|
|
- `in_review` → `approved` (approve)
|
||
|
|
- `in_review` → `published` (approve + publish)
|
||
|
|
- `in_review` → `draft` (reject)
|
||
|
|
- `approved` → `published` (publish)
|
||
|
|
- Cualquier estado → `archived` (archive)
|
||
|
|
|
||
|
|
**Implementación:**
|
||
|
|
- `ContentStatus` value object valida transiciones
|
||
|
|
- `ValidationService` orquesta workflow
|
||
|
|
- `audit_logs` registra cambios
|
||
|
|
|
||
|
|
### MedicalReview
|
||
|
|
|
||
|
|
**Estados:** `pending` → `approved` / `rejected`
|
||
|
|
|
||
|
|
**Ciclo de vida:** Asociado a `ContentItem`, no independiente.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ⚠️ Separación: Tickets vs Modelo de Dominio
|
||
|
|
|
||
|
|
### Tickets (Artefactos de Planificación)
|
||
|
|
|
||
|
|
- **TICKET-001** a **TICKET-019**: Tareas técnicas de desarrollo
|
||
|
|
- **NO son** entidades del dominio
|
||
|
|
- **NO tienen** representación en código
|
||
|
|
- **Documentados en:** `docs/QUE_FALTA.md`
|
||
|
|
|
||
|
|
### Modelo de Dominio (Entidades Reales)
|
||
|
|
|
||
|
|
- **ContentItem**, **Drug**, **GlossaryTerm**, **MediaResource**, **MedicalReview**
|
||
|
|
- **SÍ son** entidades del dominio
|
||
|
|
- **SÍ tienen** representación en código (`domain/entities/`)
|
||
|
|
- **Documentados en:** `SPEC.md`, este documento
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔮 Arquitectura Prevista (Evolución)
|
||
|
|
|
||
|
|
### Mantenimiento de Clean Architecture
|
||
|
|
|
||
|
|
- ✅ Separación de capas ya implementada
|
||
|
|
- ✅ Reglas de dependencias respetadas
|
||
|
|
- ⚠️ Posibles mejoras: más tests, más documentación
|
||
|
|
|
||
|
|
### Posibles Evoluciones
|
||
|
|
|
||
|
|
- **Event Sourcing:** Para auditoría completa (futuro)
|
||
|
|
- **CQRS:** Separar lectura/escritura si escala (futuro)
|
||
|
|
- **Microservicios:** Si el sistema crece significativamente (futuro)
|
||
|
|
|
||
|
|
**Nota:** Estas evoluciones deben documentarse en `SPEC.md` antes de implementarse.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📚 Referencias
|
||
|
|
|
||
|
|
- **Especificación maestra:** `SPEC.md`
|
||
|
|
- **Reglas de código:** `.cursorrules`
|
||
|
|
- **Tareas pendientes:** `README_TODO.md`
|
||
|
|
- **Guía de desarrollo:** `README_DEV.md`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Última actualización:** 2025-02-02
|