Academia Deltamontero · Documentación
Desarrollo

Scripts de configuración

Todos los scripts de infrastructure/moodle - arranque, configuración que corre en cada despliegue (con su clasificación crítica o cosmética), scripts de provisionamiento y lectores en Python.

infrastructure/moodle/ contiene los scripts que construyen, arrancan y configuran la plataforma. Todos los *.sh, *.php, *.py y *.json se copian a la raíz del contenedor, así que se ejecutan como php /nombre.php. Los scripts PHP de configuración son CLI de Moodle (define('CLI_SCRIPT', true); require('/var/www/html/config.php');) y son idempotentes.

Scripts de shell

ScriptCuándo correQué hace
git-at.shConstrucción de la imagenClona un repositorio en un commit exacto (Plugins de terceros).
entrypoint.shCada arranque del contenedor moodleEspera la base, genera config.php, instala Moodle si no hay tablas mdl_* (exige MOODLE_ADMIN_PASSWORD), ejecuta upgrade.php (si falla, sale con error y el despliegue se detiene), purga cachés, ejecuta moodle-config.sh, ajusta permisos y arranca Apache.
cron-entrypoint.shArranque del contenedor moodle-cronGenera config.php, espera la instalación y ejecuta el cron cada 60 s sin terminar nunca el contenedor (Tareas programadas).
write-config.shLo incluyen los dos anteriores (source)Exige MOODLE_DB_PASSWORD; espera la base hasta 5 minutos; escribe config.php con valores escapados (var_export), sslproxy si MOODLE_WWWROOT empieza por https://, reverseproxy = false, preventexecpath = true; deja el archivo en solo lectura (root:www-data, 440).
moodle-config.shCada arranque, desde entrypoint.shAplica los ajustes del sitio y ejecuta los scripts de configuración (abajo).

moodle-config.sh

Empieza con set -e y define CLI="php /var/www/html/admin/cli/cfg.php". Tiene dos tipos de instrucciones:

  • Ajustes directos con $CLI --name=… --set=…: idioma es, zona America/Guayaquil, país EC, tema boost_union con su SCSS, additionalhtmlhead (CSS y JavaScript globales, ver Interfaz global), seguridad (política de contraseñas de 10 caracteres, sesión de 2 horas, cookies seguras, bloqueo tras 10 intentos en 30 minutos, sin invitados, IP real detrás de Cloudflare y Traefik, MFA para super administradores), archivos (500 MB), correo SMTP desde las variables MOODLE_SMTP_*, rendimiento, completado y disponibilidad, página principal, calificaciones, editor, H5P, certificados, servicios web. Como el script usa set -e, un fallo en uno de estos comandos detiene el script y, con él, el arranque del contenedor.
  • Pasos con la función step <critico|cosmetico> "<descripción>" <comando>: nunca detienen el arranque. Si fallan, muestran las últimas 25 líneas de la salida en el registro y acumulan la descripción en DEPLOY_ERRORS. Al final se guarda en local_deltamodules/deploy_errors y deploy_time, y el super administrador lo ve como aviso dentro de Moodle. "Crítico" = permisos, seguridad, certificados o reglas; "cosmético" = aspecto y textos.

Pasos en cada arranque, en orden

#Script o comandoTipoQué hace
1set-logos.phpcosméticoSube logos, fondo y fuentes al almacenamiento de archivos y configura theme_boost_union. Se aplica una vez por versión (LOGOS_VERSION = 1); los cambios hechos desde la plataforma se respetan. Corre antes de calcular el logo compacto que usa el JavaScript del editor de informes.
2setup-mcp-service.phpcríticoRol, usuario de servicio, servicio externo y token del agente MCP (Servicios web). El token se muestra enmascarado.
3rename-brand.phpcosméticoMigra registros con la marca antigua en dos palabras a "Deltamontero" (sitio, categorías, plantillas). Debe ir antes de la plantilla de certificado.
4create-certificate-template.phpcosméticoPlantilla del sitio "Certificado Deltamontero" (una vez por TEMPLATE_VERSION).
5php -r en líneacosméticoCorrige customcert.deliveryoption inválido (inline → I, download → D).
6enable-video-completion.phpcríticoPasa los videos interactivos con completado manual a automático "ver hasta el final" (watchtillend).
7configure-quiz-completion-gate.phpcríticoCuestionarios: completado automático al recibir calificación y bloqueo hasta completar los videos de su sección; activa enablecompletion y enableavailability.
8apply-partial-content-by-cargo.phpcríticoContenido parcial por cargo según manual-academia.json → contenido_parcial (hoy, Tesorera en los Módulos 2 y 5): grupo por curso, temas no aplicables ocultos para ese grupo.
9gate-certificates.phpcríticoBloqueo de los certificados por completado y revocación de los emitidos a quien no cumple (Certificados).
10configure-exam-security.phpcríticoReglas de examen (academy::exam_settings) y aviso inicial a los cuestionarios que no están en examsecured; quita la ventana segura.
11normalize-academy.phpcríticohealth::repair() y standard::sweep_pending() en todos los módulos de la Academia (Módulos y estándar).
12build-intro-manual.phpcríticomanual::sync(): el curso de Introducción con el manual (Manual).
13configure-forgot-password-url.phpcríticoforgottenpasswordurl → /local/candidate_enrollment/recover.php.
14customize-strings.phpcosméticoPaquete de idioma local es_local en moodledata/lang con textos propios ($OVERRIDES), incluido el saludo con primer nombre y primer apellido.
15align-gerencia-to-manual.phpcríticodelta_gerentes sin crear ni editar usuarios (CAP_PREVENT en contexto de sistema).
16create-second-superadmin.phpcríticoCrea una vez la cuenta de super administrador de respaldo admin.respaldo con la contraseña de MOODLE_BACKUP_ADMIN_PASSWORD (sin la variable no la crea) y cambio obligatorio al primer ingreso; si la cuenta se eliminó a propósito, no la vuelve a crear. Si sigue activo el aviso de que admin usa la contraseña por defecto (alert_admin_defaultpass), lo recuerda en el registro. Ya no contiene ni detecta las contraseñas que estuvieron publicadas en versiones antiguas del repositorio. Nunca imprime contraseñas.
17enforce-real-quiz-attempts.phpcríticomod/quiz:preview en CAP_PREVENT para todos los roles: los intentos cuentan siempre (solo el super administrador previsualiza).
18enforce-course-creation-manual.phpcríticomoodle/course:create en CAP_ALLOW para delta_jefaturas y delta_ai_mcp_ro, y en CAP_PREVENT para todos los demás roles delta_*.
19align-access-profiles-to-manual.phpcríticoConcede y retira capacidades por perfil (Capacidades); acceso de revisión de la Asistente de Talento Humano al curso de selección; desactiva la automatriculación de ese curso; sincroniza el rol delta_postulante con la cohorte candidatos; crea el rol de líder; un ajuste de cohortes de una sola vez.
20align-academy-to-manual.phpcosméticoNombres de cursos y temas, objetivos y campos de revisión según manual-academia.json (índice y estructura del manual); registro en manual_applied.
21configure-dataformats.phpcosméticoFormatos de descarga: CSV + Excel, Word y PDF institucionales (Formatos de descarga).
22apply-content-responsibilities.phpcríticoRoles de curso delta_resp_contenidos y delta_gestor_m12 por cohorte de cargo en los módulos que indica manual-academia.json → responsables_contenido.
23integrate-complementary-into-m6.phpcosméticoUna vez (m6_complementary_integrated): integra los videos de "Formación Complementaria — Líderes" en los temas del Módulo 6 y recalcula certificados.
24align-enrolments-to-manual.phpcríticoUna vez (enrolments_manual_aligned_20260928): limpia matrículas de prueba que no son de la ruta del cargo.
25remove-courses-outside-manual.phpcríticoUna vez (courses_outside_manual_removed_20260929): elimina dos cursos ocultos fuera del índice del manual.
26gate-certificates.phpcríticoVuelve a calcular el bloqueo tras los cambios anteriores.
27configure-ai-groq.phpcríticoSolo si GROQ_API_KEY está definida. Crea o actualiza la instancia del proveedor Groq del chat (conector chatgpt, modelo openai/gpt-oss-20b) con esa clave. Cambiar la clave en Coolify y hacer Redeploy basta para aplicarla. Sin la variable el paso no corre y se conservan la instancia y la clave guardadas.
28configure-ai-quotas-and-persona.phpcosméticoCuotas del chat por nivel, persona plantilla del chat y ai_tiers::apply_all().
29configure-ai-terms.phpcosméticoTexto inicial de las condiciones de IA (solo la primera vez) y publicación en cada arranque.
30apply-pending-emails.phpcríticoAplica los cambios de correo que quedaron "pendientes de confirmar" en cuentas sin correo.
31rename-usernames.phpcríticopeople::fix_usernames(): nombres de usuario definitivos (tabla "usuario definitivo => nombres anteriores", sin cédulas). Solo cambia cuentas del personal con cédula registrada y si el usuario nuevo está libre.
32clean-guillemets.phpcosméticoUna vez (guillemets_cleaned_20260929; --force para repetir): quita las comillas angulares de los textos guardados (lo destacado pasa a negrita).
33set-tests-one-attempt.phpcríticoUna vez (tests_one_attempt_20260929; --force para repetir): pruebas técnicas existentes a 1 intento y test_default_attempts = 1.
34configure-mail.phpcríticoApaga el procesador de mensajes email de Moodle, limpia la dirección del sitio de los correos en cola e informa el estado del SMTP sin mostrar la clave.
35configure-course-editor.phpcosméticoMenú "Añadir una actividad o un recurso" abriendo en Recomendados con los materiales de la Academia, nombres claros (es_local) y sin el texto de relleno en los temas.
36configure-tours.phpcosméticoRecorridos guiados (Tours).
37php -r en líneacosméticoblock_ai_chat_options.historycontextmax a 50 como mínimo.
38php -r en líneacosméticoOculta la categoría por defecto de Moodle si está vacía.

Al final guarda deploy_errors y deploy_time, imprime los pasos con error y purga todas las cachés.

Scripts de provisionamiento (no corren en cada arranque)

Se ejecutan a mano desde la consola del contenedor (docker exec delta-lms_app php /script.php). La mayoría crearon la estructura inicial de la Academia; varios siguen siendo útiles para reconstruir un entorno desde cero. Todos están en la lista blanca de .dockerignore, así que están en la imagen.

ScriptQué hace
create-courses.phpCrea los cursos desde /opt/academia-dm/academia_dm_contenido.json con builder::create_module(), traduciendo los nombres cortos antiguos según manual-academia.json (shortname_anterior). Sin certificado.
restructure-courses-per-manual.phpRenombra los cursos para que coincidan con los 12 módulos del manual y crea los módulos que faltaban (vacíos). No borra nada.
create-onboarding-course.phpCrea el curso de Introducción (induccion_ia), la cohorte "Todo el equipo Deltamontero" (delta_todos) con su matrícula por cohorte, y agrega a esa cohorte a todo el personal que ya tiene una cohorte de cargo (cargo_*), sin listas de usuarios en el código. Es la misma regla que aplica manual::sync(); el personal nuevo entra solo al crearse.
create-training-paths.phpRutas por cargo (manual §7): una cohorte por cargo y su matrícula por cohorte en cada módulo obligatorio.
rebuild-roles-per-manual.phpReconstruye los 12 perfiles del manual reutilizando los 7 nombres cortos anteriores y creando 5 nuevos, con sus capacidades.
fix-role-assign-matrix-v2.phpReconstruye la matriz "Permitir asignar roles" según la gobernanza del manual.
import-personnel.phpImportación del Excel de personal por consola (--apply, --delete=all, --credentials=archivo). Ver Personas.
create-user-area-field.phpCampo de perfil de usuario "Área / Equipo" (area, tipo menú).
configure-module-metadata.phpCampos personalizados de curso (tipo de asignación, última revisión, responsable de revisión) y grupos separados en el Módulo 12.
configure-course-completion.phpAgrega el certificado que falte y el criterio de completado del curso en cada módulo (hoy lo hace academy::apply_course_completion()).
create-annual-review-event.phpEventos del sitio en el calendario para la revisión anual de los próximos 3 años.
create-review-report.phpInforme de Report Builder de revisión anual. Requiere configure-module-metadata.php.
create-training-report.phpInforme de Report Builder con el historial de formación.
grant-reports-access.phpCapacidades de reportes e historiales a Socios, Administrador de Formación, Administrador Técnico y Gerencia (hoy Gerencia las pierde con align-access-profiles-to-manual.php).
grant-policy-report-access.phpCapacidades para ver las aceptaciones (tool/policy:viewacceptances) y editar el aviso (tool/policy:managedocs).
configure-site-policy.phpActiva tool_policy y crea o actualiza en el lugar el Aviso de Tratamiento de Datos Personales.
create-selection-tests.phpCurso de la Prueba Técnica de Selección con una prueba por área del manual (4.1 a 4.4).
configure-candidate-access.phpFlujo anterior de candidatos (automatriculación con clave de grupo y consentimiento LOPDP como actividad Consulta). La automatriculación hoy la desactiva align-access-profiles-to-manual.php; el acceso es con códigos.
create-candidates-report.phpInforme de Report Builder de candidatos.
import-selection-questions.phpPreguntas provisionales en los 4 cuestionarios de selección (solo si están vacíos).
import-checkpoints.phpConvierte las preguntas de los videos del extractor (/checkpoints/c2_authored.json + c2_<content_id>.json) en un cuestionario después de cada video, emparejando por el id de YouTube.
import-rag-chunks.phpCarga chunks.jsonl en local_deltamodules_chunks con embeddings de Gemini. El propio script indica no ejecutarlo todavía.
configure-ai-manager.phpInstancia del proveedor Gemini en local_ai_manager (clave GEMINI_API_KEY).
configure-ai-chat-global.phpModo global de block_ai_chat (showonpagetypes = *) y la instancia de sistema del bloque.
apply-default-ai-persona.phpAplica la persona "Deltamontero - Asistente Academia" a todos los bloques de chat existentes.

El código ya no contiene cédulas ni las contraseñas que estuvieron publicadas, y assign-users-to-cohorts.php (lista fija de personas con su cargo) se eliminó: los cargos se asignan en Personal Deltamontero o con la importación de Excel. Los comentarios nombran roles o usan ejemplos ficticios. Lo único que queda son los nombres de usuario del personal en people::USERNAME_FIXES, que hacen falta para corregir las cuentas antiguas. Las claves actuales viven solo en las variables de entorno del servidor (Variables de entorno). El historial de Git todavía conserva los valores antiguos (ver Pendientes operativos).

Parches

patch-*.php y verify-patches.php corren solo durante la construcción de la imagen. Ver Parches.

Lectores y generadores en Python

ScriptLo usaQué hace
parse-curriculum.pyimporter::parse()Plantilla Excel, PDF, Word, CSV o JSON → módulos y temas en JSON
parse-document.pyimporter::parse($path, true)Documento libre (Word, PDF, texto) → temas por títulos, con su texto
report-docx.pyreport_export::docx()Informe en Word con la plantilla institucional

Dependencias instaladas en la imagen: python3, pypdf, python-docx, openpyxl (todas puro Python). Ver Importador y Reportes.

Datos

ArchivoContenido
manual-academia.jsonManual de Perfiles de Formación extraído a JSON: seleccion, modulos (número, nombre corto, nombre, responsable, objetivo, aplicación, temas, nombre corto anterior, número de ID), apoyo, contenido_parcial, matriz (rutas por cargo) y responsables_contenido. Lo leen los scripts align-*, apply-*, create-courses.php y otros.
checkpoints/23 archivos c2_*.json con preguntas de los videos generadas por el extractor externo, para import-checkpoints.php.
lang/es/Traducciones de plugins de terceros (Plugins de terceros).

En esta página