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
/loginPúblicoPortal de autenticación. Redirige a / tras validar credenciales.
/AutenticadoDashboard principal con las 6 cards modulares.
/adminSuper AdminConsola de administración: gestión de instituciones, usuarios y carga de PDFs.
/noticiasAutenticadoHistórico detallado de noticias nacionales con buscador y paginación.
/normativaAutenticadoBase histórica de iniciativas legislativas y decretos supremos.
/informesAutenticadoRepositorio clasificado de informes con visor y descarga de PDF.
/metricasAutenticadoTablero analítico extendido de menciones en redes sociales.
/designacionesAutenticadoDirectorio de nombramientos, designaciones y ceses en el sector.
/internacionalAutenticadoArchivo global de novedades, reformas y rankings de educación superior.

5. Administración y Servicios en el Servidor (Systemd)

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.