ANALYTICS / CDN
Analytics mediante CDN
Guía completa para identificar, entregar, reunir y consultar resultados de alumnos P2LRN mediante CDN, sin base de datos.
1. Qué hace Analytics y qué significa src
Player reproduce el curso .p2lrn y registra la actividad. La entrega offline o el capturador de Player generan un archivo .p2lrn-result por intento. Analytics no abre el curso para descubrir resultados: lee los resultados que ya existen.
<script src="https://p2lrn.org/analytics/current/dist/p2lrn-analytics.js"></script>
<p2lrn-analytics id="panel.analytics"
src="/resultados/resultado-001.p2lrn-result"></p2lrn-analytics>src es la dirección del archivo de resultados accesible para el navegador, no la del curso. id="panel.analytics" es solo el identificador HTML del panel; no es un identificador de alumno ni de curso. El componente verifica el SHA-256 y calcula las métricas disponibles sin exigir un endpoint ni una base de datos.
Disponibilidad: esta guía describe la lectura por src implementada en la rama de rediseño. Para utilizarla con el CDN o NPM públicos hay que publicar las compilaciones compatibles de Player y Analytics. Un paquete público anterior puede no tener todavía estas funciones.
2. El recorrido completo: del alumno al profesor
- Preparar: el profesor crea un curso y decide si los alumnos entran con su cuenta de plataforma o con un código individual.
- Realizar: el alumno abre el curso en Player o en una entrega offline compatible, contesta y finaliza su intento.
- Generar: se crea el archivo
.p2lrn-resultcon el identificador del curso, del alumno, del intento y la actividad disponible. - Entregar: el alumno devuelve el archivo al profesor (por el medio acordado), o la plataforma lo guarda con permisos en su almacenamiento de archivos. Player no lo envía automáticamente a Analytics ni a otro ordenador.
- Consultar: el profesor abre los archivos locales en Analytics o facilita una ruta autorizada a los mismos mediante
src. - Actualizar: al llegar nuevos archivos, los importa de nuevo o los incorpora al directorio y actualiza el índice, como se explica más abajo.
El archivo .p2lrn contiene las actividades del curso; el archivo .p2lrn-result contiene las evidencias del intento. Son archivos distintos.
3. Identificar a cada alumno: dos opciones
A. Con plataforma y sesión autenticada
La plataforma (web, campus o LMS) identifica previamente al usuario y entrega a Player su issuer (sistema emisor) y su subjectId (identificador estable del usuario). El resultado lleva esos datos, y Analytics agrupa los intentos del mismo alumno y emisor.
{
mode: 'platform',
issuer: 'campus.ejemplo',
subjectId: 'usuario-123',
label: 'Ana'
}Esos valores deben proceder de una sesión autenticada y autorizada en la aplicación integradora, nunca de un campo modificable por el alumno. Analytics puede leer la declaración del resultado, pero no demuestra por sí solo que la plataforma haya autenticado realmente al usuario.
B. Sin plataforma ni cuentas: código individual
El profesor asigna un código distinto a cada alumno, por ejemplo ALU-007, y conserva su correspondencia en su propio listado. En la entrega offline el alumno introduce el código al empezar. En una web sin cuentas, Player debe recibirlo antes de iniciar la captura. Todos los intentos de ese alumno deben utilizar el mismo código y emisor.
{
mode: 'code',
issuer: 'mi-centro',
code: 'ALU-007',
label: 'Ana'
}Importante: si dos personas introducen el mismo código, Analytics puede agrupar sus resultados como si pertenecieran al mismo alumno. El código sirve para relacionar archivos, no para acreditar la identidad.
4. Generar resultados con Player web por CDN
Una página que ya utiliza Player puede activar la captura y descargar el archivo cuando el alumno termine. Este ejemplo muestra el modo con código: sustituye ALU-007 por el código individual correspondiente y activa la captura antes de empezar las actividades.
<script src="https://p2lrn.org/player/current/dist/p2lrn.js"></script>
<p2lrn-player id="reproductor" src="/cursos/curso.p2lrn"></p2lrn-player>
<button id="descargar" type="button">Guardar mi resultado</button>
<script>
window.P2LRNReady.then(() => {
const player = document.getElementById('reproductor');
// The teacher assigned ALU-007 to this learner before starting.
player.startResultCapture({
identity: {mode:'code', issuer:'mi-centro', code:'ALU-007'}
});
document.getElementById('descargar').addEventListener('click', () =>
player.resultRecorder.download('resultado.p2lrn-result')
);
});
</script>Para usuarios autenticados, utiliza en identity el modo platform con los identificadores proporcionados por tu plataforma. La descarga debe realizarse desde una acción del alumno o un flujo de guardado autorizado; no hay envío oculto de datos.
5. Sin plataforma y sin Internet: recoger resultados locales
- El profesor distribuye las entregas compatibles y asigna un código diferente a cada alumno.
- Cada alumno introduce su código, realiza la actividad y pulsa la opción de finalizar y descargar el resultado.
- El alumno entrega su archivo
.p2lrn-resultpor memoria USB, carpeta compartida autorizada o el medio acordado. Los resultados no aparecen automáticamente en el equipo del profesor. - El profesor abre el panel Analytics y pulsa Abrir resultados para seleccionar varios archivos, o Abrir carpeta si el navegador admite esa selección.
- Analytics comprueba cada resultado, agrupa alumnos y sus intentos y presenta las métricas. Para esta modalidad no necesitas publicar un índice ni disponer de una web.
Si quieres trabajar totalmente desconectado, también debes tener disponibles localmente los archivos del propio panel Analytics. La etiqueta CDN necesita cargar el script desde Internet si no lo has alojado antes localmente.
6. Varios alumnos con src: crear el índice estático
Cuando los archivos están disponibles desde una web con acceso autorizado, no es necesario crear un endpoint. Coloca los resultados y un pequeño índice JSON en una carpeta. Los nombres del ejemplo son ficticios: usa los nombres reales de tus archivos.
resultados/
resultado-001.p2lrn-result
resultado-002.p2lrn-result
index.p2lrn-results.jsonCrea index.p2lrn-results.json con este contenido:
{
"schema": "https://p2lrn.org/schema/analytics-results-index/1",
"results": [
"resultado-001.p2lrn-result",
"resultado-002.p2lrn-result"
]
}Cada entrada de results es una ruta relativa al propio índice. Si el archivo está en la misma carpeta, basta su nombre. Todos los resultados referenciados deben encontrarse en el mismo origen web que el índice; no se aceptan URLs externas dentro de él. Se admite un máximo de 500 resultados por importación.
En tu página solo necesitas:
<p2lrn-analytics id="panel.analytics"
src="/resultados/index.p2lrn-results.json"></p2lrn-analytics>Analytics lee la lista, verifica cada archivo y reúne cursos, alumnos, intentos y puntuaciones disponibles. El índice no guarda resultados: únicamente enumera los archivos que Analytics debe abrir.
7. Cómo actualizar el índice cuando llegan más alumnos
Opción manual, sin instalar nada
- Recibe los nuevos archivos
.p2lrn-resulty colócalos en la misma carpeta con nombres únicos, sin sobrescribir intentos anteriores. - Abre
index.p2lrn-results.jsoncon un editor de texto. - Añade una entrada con el nombre exacto de cada archivo nuevo dentro de
results, separada por comas. Conserva todas las entradas anteriores. - Guarda el JSON válido y publica o copia el índice actualizado junto con los archivos, manteniendo los controles de acceso.
- En Analytics pulsa Actualizar o vuelve a abrir la página para cargar el índice nuevo. Si el navegador muestra una versión antigua, comprueba la caché HTTP del archivo índice.
Opción automática con Node.js, sin base de datos
Si recibes muchos archivos, descarga el generador de índice de resultados. Copia el script junto a la carpeta resultados y ejecútalo cada vez que lleguen nuevas entregas:
node p2lrn-results-index.mjs ./resultadosEl script busca archivos .p2lrn-result en esa carpeta (no en subcarpetas), comprueba su esquema y SHA-256, ordena sus nombres y regenera el índice completo. Si encuentra un archivo incompatible, detiene la operación sin sustituir el índice anterior. No sube información a Internet. Después debes copiar o publicar el índice y los archivos en el destino protegido.
8. Cómo llegan los archivos hasta el panel: tres escenarios
Los alumnos descargan o entregan sus .p2lrn-result. El profesor los reúne en su ordenador y los abre directamente desde Analytics. No hace falta src ni un servidor.
Alguien autorizado coloca los archivos en un almacenamiento web protegido y mantiene el índice. El panel los consulta por src. La web no descubre archivos nuevos ni los recibe por sí sola.
La aplicación puede guardar cada archivo en su almacenamiento autorizado y generar o actualizar un índice accesible al profesor. Esto requiere programar ese flujo de entrega y permisos en la plataforma, pero no una base de datos obligatoria.
Privacidad: nunca publiques los resultados identificables de alumnos en una ruta pública sin control de acceso. Un CDN público de scripts no protege por sí mismo los archivos de resultados. Si no tienes un alojamiento privado, utiliza la importación local.
9. Identificación, integridad y límites
Analytics relaciona resultados mediante la identidad declarada, el curso (assignment.packageId) y cada intento (attempt.id). Los archivos de identidad heredada pueden resultar ambiguos si comparten un identificador antiguo. Los resultados idénticos se descartan como duplicados; los archivos manipulados o incompatibles se rechazan.
SHA-256 no es una firma digital: sirve para detectar discrepancias respecto al hash incluido, pero cualquiera que reescriba el archivo podría calcular otro hash. Ni el código del alumno ni un campo mode:'platform' demuestran por sí solos quién hizo la actividad. Las notas locales siguen siendo informativas hasta que un sistema autorizado las confirme.
10. Problemas habituales y solución
Es incorrecto: usa una ruta .p2lrn-result o un índice .p2lrn-results.json.
Comprueba la dirección, la sesión autorizada, los permisos del archivo y los encabezados del alojamiento. El índice no sustituye el control de acceso.
Comprueba que se ha recibido el archivo, que aparece en el índice y que se ha actualizado el panel. Los nuevos archivos no se añaden solos al índice.
Comprueba que usan códigos distintos, o que el emisor e identificador de plataforma son estables y correctos.
No edites manualmente los resultados: vuelve a obtener el archivo original de Player. El fallo impide incluirlo en las métricas.
Usa la importación múltiple o el índice estático; una ruta directa a un archivo muestra únicamente ese resultado.
11. NPM e integración avanzada
Consulta Analytics con NPM para instalar e integrar ambos componentes, usar el capturador de Player desde JavaScript y generar los índices para una aplicación.
La integración mediante panel.data, panel.dataSource o un endpoint JSON autenticado sigue disponible cuando la plataforma ya dispone de esa infraestructura, pero no es necesaria para gestionar los archivos .p2lrn-result.
12. Player y Analytics en una plataforma propia
Los alumnos autenticados no descargan ni envían resultados. Player conserva automáticamente el mismo formato .p2lrn-result con estado in_progress y después submitted en un directorio privado del servidor. Analytics lee un índice protegido por permisos docentes, separado de los cursos .p2lrn y sin base de datos adicional.
import {createPlayerAnalyticsSession,createHttpResultHost} from '@p2lrn/player';
const host=createHttpResultHost({baseUrl:'/api/p2lrn/results',csrfToken:()=>plataforma.csrfToken});
const player=document.createElement('p2lrn-player');
const session=await createPlayerAnalyticsSession(player,{identity:{mode:'platform',issuer:usuario.issuer,subjectId:usuario.id},courseId:'ID_REAL_DEL_CURSO',host});
// Attach the Host before Player mounts so saved activity states are restored.
player.setAttribute('src','/cursos/curso.p2lrn');
document.querySelector('#player').replaceChildren(player);
// Llama a session.finish() cuando el alumno termine el curso.const panel=document.getElementById('panel.analytics');
panel.src=host.indexUrl('ID_REAL_DEL_CURSO');
await panel.refresh();El backend de referencia se importa mediante @p2lrn/player/server/results. El integrador debe proporcionar authenticate, authorize y checkCsrf para comprobar la identidad del alumno y sus permisos, así como disponer de una carpeta privada y persistente con escritura. Ni el directorio del curso ni la descarga manual intervienen. Si no se puede guardar, Player recibe un error en lugar de confirmar el resultado. El código del Host debe rechazar datos de usuarios diferentes y no publicar los resultados como archivos públicos.
Consulta la especificación spec/RESULTS-ANALYTICS.md del repositorio. Estas APIs están en el código de integración; comprueba que la versión publicada de NPM/CDN incluya el contrato antes de utilizarlo.