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.
Plugins propios
| Plugin (componente) | Carpeta en el repositorio | Ruta dentro de la imagen | Versión (version.php) | Página |
|---|---|---|---|---|
local_deltamodules | plugins/local_deltamodules | /var/www/html/local/deltamodules | 2026100701 (release 1.0) | local_deltamodules |
local_candidate_enrollment | plugins/local_candidate_enrollment | /var/www/html/local/candidate_enrollment | 2026100700 (release 1.0.0) | local_candidate_enrollment |
local_deltacerts | plugins/local_deltacerts | /var/www/html/local/deltacerts | 2026082700 (release 1.0) | local_deltacerts |
quizaccess_deltagate | plugins/quizaccess_deltagate | /var/www/html/mod/quiz/accessrule/deltagate | 2026092400 (release 1.0) | quizaccess_deltagate |
dataformat_deltaxlsx, dataformat_deltadocx, dataformat_deltapdf | plugins/dataformat/delta* | /var/www/html/dataformat/delta* | 2026092400 cada uno | Formatos 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ón | Cómo se aplica |
|---|---|
| Idioma | Comentarios, textos de interfaz y nombres de cadenas en español. Los mensajes de commit van en inglés (ver Guía de cambios). |
| Marca | Siempre "Deltamontero" (una palabra). rename-brand.php migra registros antiguos que usaban el nombre en dos palabras. |
| Encabezado de archivo | Los 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 terceros | Todo 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 propio | Los 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. |
| Idempotencia | Todos 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ágina | Los 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 acciones | Las 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ódigo | Claves 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ódigo | Ni 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 propios | Las páginas propias usan las clases dp-* de local_deltamodules\ui::css() (paneles blancos, azul corporativo #1361A4). |
| Sin comillas angulares | Decisión del proyecto: los textos no usan comillas angulares; lo destacado va en negrita (clean-guillemets.php limpió lo que quedaba en la base). |