local_pccntr8203403_dashboard
Tipo: local plugin
Ubicación: public/local/pccntr8203403_dashboard/
Versión: 1.2.0 (2026072700)
Requiere: Moodle 5.0+ (2025092600)
Alcance: 2 — Dashboard de aprendizaje (capa de datos reutilizada por el Alcance 3)
Estado: Estable
Propósito
Capa de datos del Dashboard de aprendizaje (Scope 2). Provee estadísticas de progreso, desempeño y alertas académicas del estudiante en un curso, sin acceso directo a mdl_* desde el tema o el bloque.
Clases
data\course_stats
Estadísticas de un estudiante en un curso concreto. La mayoría de las consultas usan las APIs de
Moodle (completion_info, grade_get_course_grade, get_logs). Dos métodos —
get_pending_evaluations y get_participation_counts— usan SQL directo sobre tablas core
({quiz}, {quiz_attempts}, {course_modules}, {modules}) porque no existe API equivalente.
Todos los métodos son public static.
| Método | Descripción |
|---|---|
get_user_progress(\stdClass $course, int $userid): ?array | Porcentaje de completación (completed / total × 100). Retorna null si el seguimiento de completación no está habilitado. |
get_user_module_progress(\stdClass $course, int $userid): array | Progreso desglosado por sección. Cada entrada trae [name, sectionnum, pct, complete, completedcount, totalcount, activities]. |
get_course_average_progress(int $courseid): ?float | Progreso medio del curso entre todos los matriculados. Cacheado en courseaverages. |
get_user_course_grade(int $courseid, int $userid): ?float | Calificación final del estudiante en el curso (escala 0–5). |
get_course_average_grade(int $courseid): ?float | Promedio de calificaciones de todos los estudiantes matriculados. |
get_recent_grades(int $courseid, int $userid, int $limit = 3): array | Últimas calificaciones recibidas (name, grade5, date). |
get_nearest_due_hours(\stdClass $course): ?float | Horas hasta la próxima entrega más cercana. Depende del calendario del usuario en sesión. |
get_days_since_last_access(int $courseid, int $userid): ?int | Días desde el último acceso al curso. |
get_expected_progress_pct(\stdClass $course): ?float | Porcentaje esperado de avance según la duración del curso y la fecha actual. |
get_participation_counts(int $courseid, int $userid): ?array | Conteo de participaciones en foros y actividades interactivas. |
get_pending_evaluations(\stdClass $course, int $userid): ?array | Cuestionarios sin intentar: retorna ['overdue' => bool, 'staleopen' => bool]. |
get_inactive_progress_days(int $courseid, int $userid, int $tzoffset): int | Días con acceso registrado pero sin progreso real (completaciones). |
get_modules_behind_count(\stdClass $course, int $userid): ?int | Secciones que deberían estar completas según la fecha esperada pero no lo están. |
get_user_streak(int $courseid, int $userid, int $tzoffset, bool $forcetoday): int | Días consecutivos con actividad registrada en logs. $forcetoday distingue el cálculo en web (el usuario está navegando) del cálculo por Web Service. |
get_course_average_streak(int $courseid, int $tzoffset): ?float | Racha media del curso. Cacheada en courseaverages. |
classify_progress_state(float $userpct, ?float $avgpct): string | Clasifica una métrica contra la media del curso. Devuelve excelente, bien, atencion o riesgo. |
classify_pending_state(int $userpending, ?float $avgpending): string | Equivalente al anterior para actividades pendientes (menos es mejor). |
Los valores que devuelven classify_progress_state y classify_pending_state son el campo
state que consume la función externa
get_student_panel. Cambiarlos rompe a los consumidores
externos.
data\student_stats
Estadísticas globales del estudiante (todos sus cursos). Usada por el Stats Row del Área personal (/my/).
| Método | Descripción |
|---|---|
get_active_courses(int $userid): int | Cursos con matrícula activa y visible cuya fecha de fin de matrícula sigue vigente. No aplica ninguna ventana temporal de actividad. |
get_pending_activities(int $userid): int | Total de actividades pendientes en todos los cursos activos. |
get_upcoming_events(int $userid): int | Próximos eventos del calendario Moodle del usuario. |
get_completed_courses(int $userid): int | Cursos con criterio de finalización marcado como completado. |
get_all(int $userid): array | Devuelve las cuatro métricas en una sola llamada: active_courses, pending_activities, upcoming_events, completed_courses. Es la que consume el Stats Row. |
data\academic_alerts
Motor de alertas académicas con 12 tipos (ver Alertas académicas). Presentación-agnóstico: retorna códigos + nivel + flag motivacional.
data\attention_courses
Vista transversal del motor de alertas: recorre las matrículas del estudiante y devuelve los cursos con alertas de riesgo. Usada por el bloque "Cursos que necesitan atención" del Área personal.
| Método | Descripción |
|---|---|
get_for_user($userid, $limit = 3) | Cursos con al menos una alerta no motivacional, ordenados por severidad (critico antes que leve) y luego por cantidad de alertas. Retorna [course, alertcount, topcode, toplevel]. |
Acota su costo en tres frentes: evalúa como máximo MAX_EVALUATED (10) matrículas por petición
en orden de acceso más reciente, memoiza el resultado por curso en la caché useralerts y
filtra cursos inaccesibles con can_access_course().
Optimización de rendimiento (caché)
data\course_stats cachea sus resultados en dos niveles para acotar el costo por vista de
curso: el banner "Tu desempeño académico" y la modal "Ver mi avance" invocan varios métodos
2-3 veces en la misma petición, y los agregados de curso (promedios y rachas) requieren
escanear mdl_logstore_standard_log para todos los matriculados — sin caché esto suma
~25-30 consultas por carga de course/view.php.
Memoización por request
Los métodos por usuario que se invocan varias veces en la misma petición usan un caché estático
en memoria (self::$requestcache, helper remember()), válido solo durante el request actual:
get_user_progress($course, $userid)get_user_module_progress($course, $userid)get_user_course_grade($courseid, $userid)
Caché MUC de aplicación (db/caches.php)
Los agregados de curso (iguales para todos los estudiantes, o estables durante el día) se guardan en cachés de aplicación de Moodle (MUC):
Las tres son MODE_APPLICATION con simplekeys, simpledata y staticacceleration
habilitados (staticaccelerationsize 30).
| Definición de caché | TTL | Usada por |
|---|---|---|
courseaverages | 1 hora | get_course_average_progress, get_course_average_grade, get_course_average_streak |
userstreaks | 2 días (clave incluye el día) | get_user_streak, get_inactive_progress_days |
useralerts | 2 días (clave incluye el día) | attention_courses::get_for_user — resumen de alertas de riesgo por curso y usuario |
La lógica de cómputo original de cada método se movió a un método privado compute_*(); el
método público ahora consulta la caché, y si hay miss, calcula y guarda el resultado.
Tablas de base de datos
El plugin no crea tablas propias. Consulta exclusivamente tablas core de Moodle:
| Tabla Moodle | Uso |
|---|---|
mdl_course_modules_completion | Completación de actividades |
mdl_grade_grades, mdl_grade_items | Calificaciones |
mdl_logstore_standard_log | Logs de actividad para racha y accesos |
mdl_assign_submission | Fechas límite de entregas |
mdl_event | Eventos del calendario |
mdl_course_sections | Estructura de secciones del curso |
Instalación
El plugin se instala como parte del procedimiento de despliegue
estándar (copia de código → propietario → upgrade.php → purga de cachés). No requiere
configuración adicional tras la instalación.
Dependencias
block_pccntr8203403_atenciondeclara dependencia formal sobre este plugin (version.php) y consumeattention_courses.theme_cdigitalconsume las clases de datos directamente desde su renderer (course_stats,academic_alerts) y desde el layoutmydashboard.php(student_stats).
Capa de Web Services
El plugin registra dos funciones externas de solo lectura en db/services.php, con
propósitos y modos de consumo distintos:
| Función | Modo | Consumidor |
|---|---|---|
local_pccntr8203403_dashboard_get_course_teachers | ajax => true | theme_cdigital, para la card de curso |
local_pccntr8203403_dashboard_get_student_panel | ajax => false | Servicio de IA externo, por token |
get_course_teachers
Devuelve [{courseid, teachers}] con los nombres de los docentes ("course contacts") de cada
curso, vía core_course_category::preload_course_contacts() +
core_course_list_element::get_course_contacts(). Filtra cursos inexistentes o sin acceso del
usuario. Definida en classes/external/get_course_teachers.php.
get_student_panel — Alcance 3
Expone el dataset completo del panel "Ver mi avance" de un estudiante, por curso, para consumo
del agente IA externo. Definida en classes/external/get_student_panel.php.
| Aspecto | Valor |
|---|---|
| Parámetros | userid (obligatorio), courseid (opcional, 0 = todos los cursos con matrícula activa) |
| Capacidad | local/pccntr8203403_dashboard:viewstudentpanel en contexto de curso |
| Consume | data\course_stats y data\academic_alerts |
| Retorna | userid, firstname, fullname, generatedat y una entrada por curso con progress, grade, pending, streak, modules, recentgrades y alerts |
Con courseid explícito lanza excepción si falta la capacidad o la matrícula; con courseid = 0
omite en silencio los cursos sin acceso.
La alerta due_soon no se dispara por Web Service: la API de calendario de Moodle está ligada al
usuario de la sesión, que en este flujo es la cuenta del token y no el estudiante consultado.
El contrato de integración completo, con ejemplo de llamada y diccionario de códigos de alerta, está en Consumo del panel del estudiante.
Ver: ADR-001 — Capa Web Services para datos del dashboard.
El ADR propuso el nombre provisional get_learner_context; el nombre definitivo con el que se
implementó es get_student_panel.
Capacidades
| Capacidad | Riesgo | Contexto | Arquetipos |
|---|---|---|---|
local/pccntr8203403_dashboard:viewstudentpanel | RISK_PERSONAL | CONTEXT_COURSE | Ninguno |
Se define sin arquetipos de forma deliberada: no la hereda ningún rol estándar. Debe asignarse
explícitamente al rol de la cuenta de servicio del "Componente IA Externo" — ver
Web Services IA. La cuenta necesita además moodle/course:view en
los cursos que vaya a consultar, porque la función valida el contexto del llamador.