INTEGRAR / COLABORACIÓN

Colaboración portable

P2LRN puede incluir actividades colaborativas sin meter usuarios, credenciales, servidores ni URLs de transporte dentro del paquete. El curso declara qué necesita y el host aporta identidad, permisos, sala y persistencia.

1. Actividades disponibles en Studio

Votación en directo

Los participantes votan y reciben resultados agregados. Puede permitir cambiar el voto y dispone de respuesta individual cuando la colaboración no está disponible.

Pizarra compartida

Los participantes publican notas en una sala común y pueden retirar sus propias aportaciones.

Revisión entre pares

Cada participante envía una aportación y puede comentar aportaciones de otros participantes.

Studio declara automáticamente la capacidad necesaria al crear estas actividades. El autor no configura WebSocket, Redis, tokens ni endpoints dentro del .p2lrn.

2. Contrato portable

Las tres actividades utilizan la capacidad semántica collaboration.room. El contrato inicial conserva exactamente cinco operaciones:

join

Abre la participación en una sala y devuelve una sesión opaca, revisión y presencia.

send

Envía una acción semántica de la actividad.

listen

Obtiene cambios posteriores a un cursor de revisión.

snapshot

Recupera el estado compartido necesario para abrir o reconectar.

leave

Cierra la pertenencia en vivo a la sala.

El paquete sólo conoce una sala local.

El host combina esa sala con su contexto confiable de curso, grupo, actividad y matrícula. Dos instalaciones que abran el mismo .p2lrn no comparten accidentalmente una sala global.

3. Conectar el Player con un host

El navegador incluye createHttpCollaborationProvider(). El provider traduce las cinco operaciones a un endpoint controlado por la aplicación sin cambiar el formato del paquete.

JavaScript · navegador
const provider = P2LRN.createHttpCollaborationProvider({
  endpoint: '/api/p2lrn/collaboration',
  getHeaders: () => ({
    Authorization: 'Bearer ' + shortLivedHostToken
  })
});

player.capabilityBroker = P2LRN.createCapabilityBroker({
  providers: [provider],
  authorize: ({capabilityId}) =>
    capabilityId === 'collaboration.room'
});

Por el transporte sólo cruzan identificadores portables del paquete/actividad y la operación solicitada. La identidad del alumno no la elige el paquete.

4. Handler de servidor

@p2lrn/player/server expone createP2LRNCollaborationHandler(). No existe un modo abierto por defecto: la integración debe definir origen permitido, autenticación, contexto confiable, autorización y servicio de persistencia.

Node.js · host
import {
  createP2LRNCollaborationHandler
} from '@p2lrn/player/server';

app.post('/api/p2lrn/collaboration',
  createP2LRNCollaborationHandler({
    allowedOrigins: ['https://learn.example.com'],
    authenticate: (req) => sessionUser(req),
    resolveContext: ({actor, clientContext}) =>
      resolveEnrolmentScope(actor, clientContext),
    authorize: ({actor, operation, context}) =>
      canCollaborate(actor, operation, context),
    service: collaborationStore
  })
);

La persistencia puede utilizar PostgreSQL, Redis, almacenamiento propio, un servicio durable u otra solución del host. P2LRN no obliga a desplegar una tecnología concreta.

5. Seguridad y fallback

Identidad

La asigna el host autenticado. El handler rechaza intentos del paquete de fijar participantId, actorId, userId, identity o principal.

Orígenes

El handler requiere una allowlist explícita y HTTPS para endpoints absolutos no locales.

Permisos

El host autoriza cada operación con su propio contexto de usuario, curso, grupo y actividad.

Sin servicio

Si la capacidad es opcional y no está disponible, el Player conserva un recorrido individual en lugar de hacer ilegible el paquete.

6. Analítica de las actividades colaborativas

Las acciones relevantes se integran con el mismo sobre de eventos del Player mediante p2lrn:interaction. Ejemplos: voto, añadir/eliminar una nota de pizarra, enviar una aportación o publicar una revisión. La identidad real del participante sigue siendo responsabilidad del host y no se copia al paquete.