Documentación Oficial de Arquitectura v2.0
Observatorio de Educación Superior (OES)
Especificación técnica integral: Infraestructura, árbol de ficheros, modelo de datos relacional, endpoints API y esquema de seguridad B2B.
1. Stack Tecnológico de Producción
Infraestructura & OS
DigitalOcean Droplet en Ubuntu Server LTS (IP: 67.205.157.204).
Servidor Web & Proxy Inverso
Nginx 1.24.0 redirigiendo tráfico HTTP/80 hacia el socket local 127.0.0.1:8000.
Backend Core & ASGI
Python 3.12, FastAPI, Uvicorn Workers orquestados con Gunicorn (servicio oes.service).
Base de Datos Relacional
PostgreSQL con motor transaccional para clientes, usuarios, reportes y sumillas.
Automatización & Broker
Redis + Celery (oes_worker) y Celery Beat (oes_beat) para scrapers a las 06:30 y 14:30.
Cifrado & Autenticación
JSON Web Tokens (JWT) firmados con algoritmo HS256 y hashing nativo mediante bcrypt con truncado seguro a 72 bytes.
Frontend & UI
HTML5, Tailwind CSS (vía CDN), interactividad ligera reactiva con Alpine.js v3 y gráficos en Chart.js.
Procesamiento Documental
PyMuPDF (fitz) para lectura y estructuración de archivos PDF cargados manualmente.
2. Estructura y Árbol de Ficheros (/var/www/oes_platform)
/var/www/oes_platform/
├── app/
│ ├── api/
│ │ ├── __init__.py
│ │ ├── admin.py # Gestión B2B: instituciones, creación de usuarios y billing
│ │ ├── auth.py # Autenticación JWT, verificación nativa con bcrypt y login
│ │ ├── dashboard.py # Resumen de 6 módulos para la vista principal (/api/dashboard/summary)
│ │ ├── deps.py # Inyección de dependencias (OAuth2, get_current_user, require_super_admin)
│ │ ├── modules.py # Endpoints de consulta para históricos con paginación y búsqueda
│ │ ├── reports.py # Subida multipart de PDFs oficiales y lectura de binarios
│ │ └── scrapers.py # Disparadores manuales y endpoints de auditoría de ingesta
│ ├── core/
│ │ ├── __init__.py
│ │ ├── config.py # Configuración central (SECRET_KEY, ALGORITHM, EXPIRE_MINUTES)
│ │ └── db.py # Sesión SQLAlchemy y engine conectado a PostgreSQL
│ ├── models/
│ │ ├── __init__.py
│ │ └── entities.py # Modelos relacionales: User, Institution, News, Legals, Reports, etc.
│ ├── scrapers/ # Scripts de extracción (Playwright, BeautifulSoup) de El Peruano y Congreso
│ └── templates/ # Plantillas servidas por FastAPI (Jinja2 / Alpine.js)
│ ├── admin.html # Consola administrativa para altas y gestión comercial
│ ├── appointments.html # Módulo histórico de designaciones y ceses
│ ├── dashboard.html # Tablero principal de 6 cards reactivas
│ ├── international.html# Módulo histórico de educación superior en el extranjero
│ ├── legal.html # Módulo histórico de proyectos de ley y decretos
│ ├── login.html # Formulario de login obligatorio
│ ├── metrics.html # Módulo histórico de métricas y tendencias en redes
│ ├── news.html # Módulo histórico de coyuntura periodística nacional
│ └── reports.html # Repositorio de informes y balances PDF
├── static/
│ ├── docs/ # Documentación accesible vía web
│ └── uploads/ # Directorio protegido de almacenamiento físico de PDFs
├── main.py # Punto de entrada FastAPI, middlewares y montaje de routers
└── venv/ # Entorno virtual aislado Python 3.12
3. Arquitectura del Modelo de Datos (PostgreSQL)
| Tabla |
Campos Principales |
Descripción |
institutions |
id, name, tax_id (RUC), plan_type, billing_status, monthly_fee, max_users |
Clientes B2B (universidades, gremios). Estatus: ACTIVE, TRIAL, SUSPENDIDO. |
users |
id, institution_id, email, password_hash, full_name, role, is_active |
Usuarios del sistema. Roles: SUPER_ADMIN, INSTITUTION_ADMIN, CLIENT_VIEWER. |
news_articles |
id, title, summary, source_name, source_url, publication_date, is_international |
Noticias nacionales e internacionales recopiladas por scraping. |
legal_initiatives |
id, code_identifier, type, title, summary, proponent, status, official_source_url |
Proyectos de ley del Congreso y decretos publicados en El Peruano. |
public_appointments |
id, resolution_number, entity, action_type, person_name, position_title, date |
Nombramientos y ceses en MINEDU, SUNEDU, SINEACE y universidades públicas. |
educational_documents |
id, title, summary, file_path, file_size_bytes, category, uploaded_by |
Informes y balances oficiales en PDF cargados por el Administrador. |
social_metrics |
id, platform, university_target, topic, mentions_volume, sentiment_score |
Monitoreo de tendencias y volumen de conversación sobre educación superior. |
4. Mapa de Rutas Web y Endpoints API
4.1. Vistas Web de Frontend (HTML / Alpine.js)
| Ruta URL |
Acceso |
Descripción Funcional |
/login | Público | Portal de autenticación. Redirige a / tras validar credenciales. |
/ | Autenticado | Dashboard principal con las 6 cards modulares. |
/admin | Super Admin | Consola de administración: gestión de instituciones, usuarios y carga de PDFs. |
/noticias | Autenticado | Histórico detallado de noticias nacionales con buscador y paginación. |
/normativa | Autenticado | Base histórica de iniciativas legislativas y decretos supremos. |
/informes | Autenticado | Repositorio clasificado de informes con visor y descarga de PDF. |
/metricas | Autenticado | Tablero analítico extendido de menciones en redes sociales. |
/designaciones | Autenticado | Directorio de nombramientos, designaciones y ceses en el sector. |
/internacional | Autenticado | Archivo global de novedades, reformas y rankings de educación superior. |
5. Administración y Servicios en el Servidor (Systemd)
oes.service: Proceso principal de FastAPI ejecutado a través de Gunicorn con workers Uvicorn.
oes_worker.service: Worker asíncrono de Celery para scraping y procesamiento de PDFs.
oes_beat.service: Planificador de Celery Beat para la ejecución periódica de ingesta.
nginx: Servidor proxy que recibe las peticiones en el puerto 80 y las delega al backend.
postgresql: Base de datos relacional transaccional.
redis: Message broker y almacenamiento en memoria para la cola de tareas.
6. Módulo Analítico del Dashboard (Chart.js)
El tablero principal implementa un contenedor analítico inferior montado sobre Chart.js (v4.x CDN) que consolida métricas semanales mediante dos canvas interactivos:
| Canvas ID |
Tipo de Gráfico |
Fuentes de Datos |
Parámetros Representados |
chartSocialTrends |
Line Chart (Curva suavizada) |
social_metrics |
Evolución cronológica de 7 días dividida en dataset positivo/neutro (border solid #2563eb) y dataset crítico (dashed #ef4444). |
chartLegalDist |
Bar Chart (Barras redondeadas) |
legal_initiatives & public_appointments |
Distribución por origen de emisión regulatoria: Congreso (PL), El Peruano, SUNEDU, MINEDU y Resoluciones Universitarias. |