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
Participants vote and receive aggregated results. It can allow changing the vote and has individual response when collaboration is not available.
Participants post notes in a common room and can withdraw their own contributions.
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:
joinOpens participation in a room and returns an opaque session, review, and presence.
sendSends a semantic action of the activity.
listenGets changes after a revision cursor.
snapshotRecovers the shared state required to open or reconnect.
leaveClose live membership to the 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.
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.
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
It is assigned by the authenticated host. Handler rejects packet attempts to fix participantId, actorId, userId, identity or principal.
The handler requires an explicit allowlist and HTTPS for absolute non-local endpoints.
The host authorizes each operation with its own user, course, group, and activity context.
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.