INTEGRATE / COLLABORATION

Portable collaboration

P2LRN can include collaborative activities without putting users, credentials, servers, or transport URLs into the package. The course declares what it needs and the host provides identity, permissions, room and persistence.

1. Activities available in Studio

Live voting

Participants vote and receive aggregated results. It can allow changing the vote and has individual response when collaboration is not available.

Shared board

Participants post notes in a common room and can withdraw their own contributions.

Peer review

Each participant sends a contribution and can comment on contributions from other participants.

Studio automatically declares the required capacity when creating these activities. The author does not configure WebSocket, Redis, tokens or endpoints within the .p2lrn.

2. Portable contract

The three activities use semantic capacity collaboration.room. The initial contract preserves exactly five operations:

join

Opens participation in a room and returns an opaque session, review, and presence.

send

Sends a semantic action of the activity.

listen

Gets changes after a revision cursor.

snapshot

Recovers the shared state required to open or reconnect.

leave

Close live membership to the room.

The package only knows one local room.

The host combines that room with its trusted course, group, activity, and enrollment context. Two facilities that open the same .p2lrn They don't accidentally share a global room.

3. Connect the Player to a host

The browser includes createHttpCollaborationProvider(). The provider translates all five operations to an endpoint controlled by the application without changing the packet format.

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

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

During transport, only portable identifiers of the package/activity and the requested operation cross. The identity of the learner is not chosen by the package.

4. Server Handler

@p2lrn/player/server exposes createP2LRNCollaborationHandler(). There is no open mode by default: the integration must define allowed origin, authentication, trusted context, authorization, and persistence service.

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
  })
);

Persistence can use PostgreSQL, Redis, self-storage, a durable service, or another host solution. P2LRN does not require the deployment of a specific technology.

5. Security and fallback

Identity

It is assigned by the authenticated host. Handler rejects packet attempts to fix participantId, actorId, userId, identity or principal.

Origins

The handler requires an explicit allowlist and HTTPS for absolute non-local endpoints.

Permissions

The host authorizes each operation with its own user, course, group, and activity context.

No service

If the capability is optional and not available, the Player preserves an individual tour rather than making the packet unreadable.

6. Analytics of collaborative activities

The relevant actions are integrated with the same Player event envelope using p2lrn:interaction. Examples: vote, add/delete a whiteboard note, submit a contribution, or post a review. The actual identity of the participant remains the responsibility of the host and is not copied to the packet.