Academia Deltamontero · Documentación
El proyecto

Decisiones técnicas

Decisiones tecnológicas y de diseño del proyecto, su justificación, las alternativas descartadas y las que siguen abiertas.

Esta página recoge las decisiones registradas en la guía del repositorio, en los documentos de planificación (docs/roadmap*.md, docs/PROYECTO_LMS_DELTA_MONTERO_contexto.md), en el manual de recuperación (docs/drp.md) y en los comentarios del código. Las primeras once figuran en la guía como decisiones cerradas, que no deben reabrirse.

Resumen

#DecisiónElegidoDescartado o reemplazadoEstado
1Plataforma de aprendizajeMoodle 4.5 LTSMoodle 4.1 a 4.4; software propio de Talento HumanoCerrada
2Base de datosMariaDB 11.4 LTSPostgreSQL (mencionado como alternativa en el plan inicial)Cerrada
3ContenedoresDocker para todos los servicios—Cerrada
4DespliegueCoolify—Cerrada
5Proxy inversoTraefik (el que administra Coolify)Etiquetas de Traefik manuales en producciónCerrada
6CDN y proxy públicoCloudflare—Cerrada
7Control de versionesGitHub (repositorio privado)—Cerrada
8Proveedor de IA del chatGroq, por medio de local_ai_managerGeminiVigente
9Plataforma para RAGDify (planificado)Python FastAPI con ChromaDB; .NET Semantic Kernel con QdrantCerrada, sin implementar
10Base vectorialLa que gestiona Dify (Qdrant como alternativa)ChromaDBCerrada, sin implementar
11Modelo de embeddingsbge-m3OtrosCerrada, sin implementar
12VideosYouTube (no listados) insertados; Cloudflare R2 para los no disponiblesAlojarlos en el servidorVigente
13Pruebas de postulantesDentro de MoodleGoogle FormsCerrada
14RespaldoRespaldo completo desde el servidorCopias por curso automáticas de MoodleVigente; destino externo abierto
15CorreoOffice 365 institucional con cola propiaBrevo (mencionado en el plan)Vigente
16ConfiguraciónConfiguración como código, reaplicada en cada despliegueAjustes manuales en la interfazVigente
17PermisosEl manual de perfiles al pie de la letraPermisos del arquetipo de MoodleVigente

Plataforma

Moodle 4.5 LTS

Por qué: las librerías de H5P recibieron en octubre de 2024 una actualización crítica que dejó de funcionar en versiones de Moodle anteriores a la 4.3, sin corrección para las versiones viejas. La 4.5 es la versión de soporte extendido (LTS) más baja que es segura para todo el conjunto. La guía prohíbe instalar 4.1, 4.2, 4.3 o 4.4.

Contexto: según el plan v3, Deltamontero pasó de un plan de software propio centrado en Talento Humano a Moodle por decisión de la jefatura de TI, y la planificación demostró que los objetivos del plan original cabían en Moodle sin sistemas satélite.

Consecuencias:

  • Algunos complementos de terceros quedan fijados a la última versión compatible con 4.5: local_ai_manager v1.1 y block_ai_chat v1.0 (sus versiones 2.x exigen Moodle 5.0); mod_customcert en la rama 4.4, compatible con 4.5; tool_certificate y mod_coursecertificate en la rama 4.0, que cubre hasta 4.5.
  • El plan v4 prevé una migración a la siguiente LTS en 2027, incluida la versión 2.x de local_ai_manager.

Complementos fijados a un commit exacto

Todos los complementos de terceros se descargan durante la construcción de la imagen en un commit exacto (script git-at), salvo local_ai_manager, tiny_ai y block_ai_chat, que se fijan por etiqueta de versión. Por qué: un cambio del autor no puede romper la imagen ni desactivar en silencio un parche propio. Los parches sobre complementos de terceros se comprueban al construir (verify-patches.php) y la construcción falla si alguno no quedó aplicado.

MariaDB 11.4 LTS

Base de datos de Moodle, versión de soporte extendido. El plan inicial mencionaba PostgreSQL como alternativa; la decisión cerrada es MariaDB.

Infraestructura

Docker, Coolify, Traefik y Cloudflare

PiezaPapelJustificación registrada
DockerTodos los servicios en contenedores: base de datos, sitio y cron (misma imagen)Portabilidad: migrar de servidor es clonar el repositorio, construir y restaurar datos. El servidor es desechable.
CoolifyPlataforma de despliegue en producción; variables de entorno y secretosDespliegue desde el repositorio con interfaz gráfica.
TraefikProxy inverso internoEn producción se usa el de Coolify: las etiquetas manuales de Traefik chocaban con las que genera Coolify y causaban un error 502 (8 de septiembre de 2026). Para recuperación sin Coolify existe un perfil standalone con Traefik propio.
CloudflareCDN y proxy público del dominio (planificado: hoy la Academia se usa en la red interna, en http://192.168.0.192)Las IP de Cloudflare son las únicas permitidas en el firewall del servidor (según el plan). La plataforma toma la IP real del usuario de las cabeceras de Cloudflare y Traefik.

Principio "Docker primero, servidor al final" (plan v4): todo se construye y prueba en Docker y la elección del servidor no frena el desarrollo. El plan recomendaba una máquina virtual con Ubuntu Server; según el manual de recuperación, la producción corre hoy en un contenedor LXC de Proxmox (172246, con Coolify dentro), con el reloj en UTC, y se usa desde la red interna en http://192.168.0.192.

Política de actualizaciones (plan v4, cerrada): actualizaciones automáticas solo de seguridad; el resto (núcleo del sistema, imágenes, complementos) de forma manual, con aprobación de TI y prueba previa, bajo la regla "si funciona, no se toca".

Configuración como código frente a datos en el respaldo

Decisión (plan v4, §2.2): la configuración (ajustes, tema, complementos, plantilla de certificado, estructura de la Academia, permisos) vive en el repositorio y se reaplica de forma idempotente en cada arranque del contenedor. El respaldo guarda solo lo que generan las personas: usuarios, matrículas, notas, intentos, archivos y certificados.

Por qué: tras un desastre, la configuración se reaplica sola al levantar la imagen y los datos se restauran del respaldo, sin pasos manuales. Por la misma razón, contenido como el curso de Introducción se reescribe desde el código en cada despliegue: editarlo a mano no sirve.

Respaldo completo desde el servidor

Decisión: el servidor hace cada día un respaldo de la base de datos y de los archivos (moodledata) con sumas de verificación; las copias por curso automáticas de Moodle se apagan.

Por qué: las copias por curso duplicarían cada curso dentro de moodledata y harían crecer el respaldo real sin aportar nada. El código y la configuración no necesitan respaldo porque se reconstruyen desde el repositorio.

Evolución: los planes v3 y v4 proponían una copia externa en Backblaze B2 con clave sin permiso de borrado y cifrado asimétrico con GPG, partiendo del supuesto de que el servidor podría volver a ser comprometido. El plan v2 eligió rclone con Cloudflare R2. El manual de recuperación vigente recomienda Cloudflare R2 con un remoto cifrado de rclone, y deja como alternativas un NAS de la empresa u OneDrive. El destino sigue sin elegirse.

Seguridad de acceso

DecisiónDetalle
Verificación en dos pasosSolo para super administradores (aplicación de autenticación). El plan v4 proponía exigirla también a perfiles de gestión.
Dos super administradoresUno restablece al otro sin depender del correo.
Super administrador sin candadosEl super administrador se salta los bloqueos de repasos y certificados para poder verificar que todo funciona; ningún otro perfil lo hace.
Bloqueo de cuenta10 intentos fallidos en 30 minutos.
Sin invitadosNo hay acceso de invitados.
Secretos fuera del códigoClaves de base de datos, correo e IA solo en variables de entorno de Coolify y en un gestor de contraseñas.
Página principal públicaLa portada institucional es visible sin sesión (con los accesos para colaboradores, postulantes y clientes); el contenido de los módulos exige iniciar sesión.

Inteligencia artificial

Proveedor del chat: Groq

Decisión: el chat usa Groq (modelo openai/gpt-oss-20b; el agente de acciones usa openai/gpt-oss-120b), conectado mediante el conector compatible con OpenAI de local_ai_manager. La clave se define en la variable de entorno GROQ_API_KEY.

Por qué: Gemini, el primer proveedor, daba errores 503 intermitentes por alta demanda en su nivel gratuito. Groq es más estable y rápido, ofrece más cuota gratuita y, según la configuración documentada, no entrena con los datos ni los retiene por defecto. El plan v4 ya había elegido Groq como LLM del chat.

Modelo local: la decisión cerrada prevé Ollama para desarrollo y pruebas, y una API externa en producción.

Agente de acciones dentro de Moodle

El plan v2 prefería un agente de administración en Dify con la API REST de Moodle y descartaba un servidor MCP propio. Lo implementado es:

  • un agente de acciones dentro del complemento propio, con llamadas a funciones del modelo, que se ejecuta como la persona conectada y exige confirmación en las acciones de escritura (principio "la IA propone, Moodle dispone", alineado a ISO 42001 y NIST);
  • un servicio web MCP (complemento webservice_mcp) con una cuenta técnica y un rol acotado, para un cliente de IA de administración externo.

RAG con Dify (planificado)

Decisión (junio de 2026): el chat que busca en el contenido de los cursos se hará con Dify, plataforma de código abierto autoalojada.

Por qué se descartó el servicio propio: el plan original (Python FastAPI con ChromaDB, y .NET Semantic Kernel con Qdrant en el repositorio hermano) exigía desarrollo continuo, obligaba a editar variables y volver a desplegar para cambiar de proveedor de IA, y requería reindexar a mano al agregar cursos. Dify permite cambiar el modelo desde su interfaz, configurar el RAG sin programar e ingerir contenido nuevo por API.

Principio de portabilidad: Moodle habla siempre con un único punto compatible con OpenAI; la fuente de verdad del RAG es texto con metadatos sin vectores (chunks.jsonl), y los vectores se pueden regenerar. El modelo de respuesta se cambia sin reindexar; el de embeddings (bge-m3) quedó fijo porque cambiarlo obliga a reindexar todo.

Decisión abierta: usar la base de conocimiento nativa de Dify (un segmento por fragmento) o, si su fragmentación daña los enlaces con marca de tiempo a los videos, una API de conocimiento externa con Qdrant.

Dify no está desplegado y el conector local_dify_sync no existe en el repositorio. Además, hay una alternativa preparada y no ejecutada: una tabla de fragmentos en la misma base de Moodle y un importador con embeddings de Gemini (import-rag-chunks.php). Qué camino se sigue está por confirmar.

Contenido y procesos

Videos fuera del servidor

Decisión: los videos se insertan desde YouTube (no listados); está prohibido alojarlos en el servidor interno por la política de respaldo. mod_interactivevideo añade interactividad sobre el video insertado. Los videos que ya no están disponibles en YouTube se suben a Cloudflare R2. Cada tema conserva su código PowerBuilder como identificador único para vincularlo con el sistema interno.

Pruebas de selección dentro de Moodle

Descartado: Google Forms. Por qué: los resultados quedarían en un sistema externo que habría que conciliar con Moodle, la calificación automática es más pobre que el motor de cuestionarios de Moodle y los datos personales de los postulantes saldrían del perímetro de protección de datos. Con Moodle, cuando se contrata al postulante se conserva la misma cuenta y su prueba queda en su historial, sin fusionar datos.

Evolución del flujo: se planificó un formulario tipo quiosco con cédula; luego se usó una clave por área; la versión final es un registro con código de acceso que genera Talento Humano, con cargo, vencimiento y número de usos.

Seguir el manual al pie de la letra

Decisión: los permisos, rutas, módulos y responsabilidades siguen el manual de perfiles exactamente. Los perfiles de Gerencia y Administrador Técnico nacieron del arquetipo de gestor de Moodle, que concede mucho más; los scripts de despliegue les quitan lo que el manual no les da. Ejemplo: el 22 de septiembre de 2026 se permitió a Gerencia crear usuarios como excepción y el 23 se revirtió para cumplir el manual (§12.1 y §13.1: Talento Humano crea y habilita usuarios). Solo el Jefe de Talento Humano crea módulos.

Correo institucional por Office 365

Decisión: todos los correos salen desde la cuenta institucional de Office 365 (puerto 587, STARTTLS), con una cola propia que respeta el límite del buzón, registro de envíos y enlaces de un solo uso. Las notificaciones internas de Moodle se quedan en la campana y no salen por correo. Por qué: Office 365 acepta unos 30 correos por minuto por buzón y rechaza remitentes distintos de la cuenta que inicia sesión. Sin correo configurado, la plataforma sigue funcionando y la contraseña se recupera con la cédula.

Interfaz propia sobre Moodle

Decisión: pantallas propias para las tareas de Talento Humano (Módulos, Personal, Postulantes, Clientes, Reportes, Reglas) en lugar de las pantallas genéricas de Moodle, que se ocultan o redirigen. Por qué: el objetivo es que personal no técnico opere la plataforma sin ayuda de TI. Las pantallas completas de Moodle siguen disponibles para el super administrador.

Estilos del chat incrustados en la página

Los estilos y el comportamiento del chat de IA se insertan directamente en la cabecera de cada página, sin depender de las cachés del tema. Por qué: en producción se servían versiones antiguas de los archivos en caché tras un despliegue.

Decisiones abiertas

DecisiónOpciones registradasQuién decide
Destino de la copia externa de respaldosCloudflare R2 (recomendado), NAS de la empresa, OneDrive o SharePointGerencia y TI
Cuenta de Cloudflare R2Migrar la cuenta personal que hoy aloja videos a una cuenta de la empresaGerencia
LLM externo de producción a largo plazoGroq hoy; el plan mencionaba OpenRouter, Gemini u OpenAI, entre otrosDesarrollador principal y TI
Camino del RAGDify con base nativa, Dify con Qdrant externo o la tabla de fragmentos en MariaDBDesarrollador principal
Protocolo de integración con PowerBuilderHTTP/REST o COM+/DCOMTI
Almacenamiento de los artefactos del extractor de contenidoCloudflare R2, Backblaze B2, MinIO o HTTPDesarrollador principal
Reranker del RAGBGE local, Cohere o ningunoDesarrollador principal, tras la prueba de concepto

En esta página