Academia Deltamontero · Documentación
Desarrollo

Desarrollo

Referencia técnica del código de la Academia Deltamontero para quien mantenga o extienda la plataforma.

Esta sección describe el código propio de la Academia Deltamontero (DELTA-APP): los plugins de Moodle desarrollados para el proyecto, los plugins de terceros que se incluyen en la imagen, los parches que se les aplican y los scripts que configuran la plataforma en cada arranque. Está pensada para quien deba corregir, mantener o ampliar la plataforma.

La plataforma corre sobre Moodle 4.5 LTS con PHP 8.3 (imagen base moodlehq/moodle-php-apache:8.3). Todo el código propio se escribe para esa versión: los version.php de los plugins exigen $plugin->requires = 2024100700.

Estructura del repositorio

Solo se muestra lo que interviene en el código de la plataforma. La documentación de infraestructura, respaldos y despliegue está en Arquitectura y Operación.

docker-compose.yml
docker-compose.override.yml
.dockerignore
Dockerfile
git-at.sh
entrypoint.sh
cron-entrypoint.sh
write-config.sh
moodle-config.sh
patch-*.php (11 parches)
verify-patches.php
*.php (scripts de configuración y provisionamiento)
parse-curriculum.py
parse-document.py
report-docx.py
manual-academia.json

Plugins propios

Plugin (componente)Carpeta en el repositorioRuta dentro de la imagenVersión (version.php)Página
local_deltamodulesplugins/local_deltamodules/var/www/html/local/deltamodules2026100701 (release 1.0)local_deltamodules
local_candidate_enrollmentplugins/local_candidate_enrollment/var/www/html/local/candidate_enrollment2026100700 (release 1.0.0)local_candidate_enrollment
local_deltacertsplugins/local_deltacerts/var/www/html/local/deltacerts2026082700 (release 1.0)local_deltacerts
quizaccess_deltagateplugins/quizaccess_deltagate/var/www/html/mod/quiz/accessrule/deltagate2026092400 (release 1.0)quizaccess_deltagate
dataformat_deltaxlsx, dataformat_deltadocx, dataformat_deltapdfplugins/dataformat/delta*/var/www/html/dataformat/delta*2026092400 cada unoFormatos de descarga

La carpeta plugins/local_team_management está vacía (solo contiene .gitkeep) y no se copia a la imagen. La gestión de equipos que el proyecto preveía para ese plugin se implementó dentro de local_deltamodules (clase team, página team.php, tablas local_deltamodules_team y local_deltamodules_teammem). Ver Equipos.

La carpeta rag-service/ del repositorio no forma parte de la imagen de Moodle (no está en la lista blanca de .dockerignore). Su estado se describe en Arquitectura.

Cómo llega el código a la imagen

Moodle y todos los plugins (propios y de terceros) se hornean en la imagen Docker: el contenedor no monta /var/www/html desde el host. Solo moodledata es un volumen persistente. Por eso cualquier cambio de código exige reconstruir la imagen (o copiar archivos a mano en un entorno local, ver Guía de cambios).

Contexto de construcción filtrado

.dockerignore funciona como lista blanca: empieza con ** (excluir todo) y luego habilita archivo por archivo. Un script nuevo en infrastructure/moodle/ o un plugin nuevo en plugins/ que no se agregue a esa lista no llega a la imagen, aunque el Dockerfile lo copie.

Moodle y plugins de terceros con versión fija

El Dockerfile instala Moodle 4.5 y los plugins de terceros con git-at (infrastructure/moodle/git-at.sh), que clona un repositorio en un commit exacto. Tres plugins de la familia de IA se clonan por etiqueta (--branch v1.1 / v1.0). Detalle en Plugins de terceros.

Scripts y recursos

En una sola capa se copian a la raíz del contenedor todos los *.sh, *.php, *.py y *.json de infrastructure/moodle/ (por eso se invocan como php /nombre-del-script.php), además de checkpoints/ en /checkpoints. El comentario del Dockerfile explica que se hace en una capa porque con un COPY por script se superó el límite de 127 capas de Docker.

También se copian: docker-compose.yml e infrastructure/scripts/ a /opt/delta-lms/ (para instalar los respaldos en el servidor), los logos a /opt/delta-logos/, las fuentes a /opt/delta-fonts/, docs/modules-info/academia_dm_contenido.json a /opt/academia-dm/ y la plantilla institucional de informes (assets/reports/) a /opt/delta-reports/.

Plugins propios

Cada plugin propio se copia con un COPY a su ruta de Moodle (tabla de arriba). Después se copian las traducciones al español de plugins de terceros (infrastructure/moodle/lang/es/ sobre /var/www/html/) y se ajusta el dueño (www-data) solo de las carpetas propias.

Parches y verificación

Se aplican los parches patch-*.php sobre el código de Moodle y de los plugins de terceros, en un orden fijo, y al final verify-patches.php comprueba que los importantes quedaron aplicados: si falta uno, el build falla. Ver Parches.

Arranque

entrypoint.sh espera la base de datos, genera config.php (write-config.sh), instala Moodle si la base no tiene tablas mdl_*, ejecuta upgrade.php (si falla, el despliegue se detiene), purga cachés y corre moodle-config.sh, que aplica ajustes y ejecuta los scripts de configuración. Ver Scripts de configuración.

Convenciones del código

Las siguientes convenciones se desprenden del código existente y conviene mantenerlas:

ConvenciónCómo se aplica
IdiomaComentarios, textos de interfaz y nombres de cadenas en español. Los mensajes de commit van en inglés (ver Guía de cambios).
MarcaSiempre "Deltamontero" (una palabra). rename-brand.php migra registros antiguos que usaban el nombre en dos palabras.
Encabezado de archivoLos archivos propios empiezan con un bloque // DELTA-APP LMS — … que explica qué hace, por qué y quién lo usa.
Marcas en código de tercerosTodo cambio sobre código de Moodle o de un plugin de terceros lleva un comentario DELTA: que sirve de marcador de idempotencia y de verificación (verify-patches.php).
Lógica en el plugin propioLos parches a terceros son mínimos (una o pocas líneas que llaman a una clase de local_deltamodules); la lógica vive en el plugin propio.
IdempotenciaTodos los scripts de configuración se pueden ejecutar varias veces. Los cambios de "una sola vez" usan una marca en la configuración del plugin (set_config(FLAG, time(), 'local_deltamodules')).
Nunca romper una páginaLos observadores y hooks con lógica que puede fallar la envuelven en try/catch y registran el error con debugging(): un fallo no impide guardar una actividad, enviar un examen ni cargar una página.
Seguridad de las accionesLas acciones que cambian datos usan POST con sesskey (ui::post_button) y piden confirmación con el modal de Moodle (atributo data-delta-confirm), nunca con confirm() del navegador.
Sin secretos en el códigoClaves de IA, correo y contraseñas de administración se leen de variables de entorno (GROQ_API_KEY, GEMINI_API_KEY, MOODLE_SMTP_*, MOODLE_BACKUP_ADMIN_PASSWORD…).
Sin datos personales en el códigoNi cédulas, ni contraseñas, ni listas de personas: las reglas se aplican por cargo, cohorte o perfil, y los comentarios nombran roles. Cada tabla con datos de personas se declara en el proveedor de privacidad del plugin (ver Guía de cambios).
Estilos propiosLas páginas propias usan las clases dp-* de local_deltamodules\ui::css() (paneles blancos, azul corporativo #1361A4).
Sin comillas angularesDecisión del proyecto: los textos no usan comillas angulares; lo destacado va en negrita (clean-guillemets.php limpió lo que quedaba en la base).

Mapa de esta sección

En esta página