Skip to content

Collaborative Features


Collaborative Code Editor

Used in live interview rooms (live_1on1, culture_fit_hr) and AI-assisted sessions.

Technology Stack

  • Yjs — CRDT (Conflict-free Replicated Data Type) for real-time collaboration
  • y-codemirror.next — Yjs binding for the CodeMirror 6 editor
  • y-webrtc — Yjs WebRTC provider (syncs via WebRTC Data Channels, same P2P connection as video)

How It Works

Interviewer types code in CodeMirror

CodeMirror change → Yjs operation

Yjs encodes operation as binary update

y-webrtc sends update via WebRTC Data Channel

Peer receives update → Yjs merges (CRDT = no conflicts)

Peer's CodeMirror editor reflects the change

Cursor Awareness

The awareness protocol syncs cursor positions and selections between all participants in real time. Each user's cursor is shown with their name label.

Visibility

The IDE panel in the room is visible to all participants (interviewer + candidate). It is controlled by StageTypeConfig.toolsConfig.ide — the panel only renders when true.


Whiteboard

Real-time shared canvas using Excalidraw.

  • Excalidraw's built-in collaboration API is used to broadcast element changes
  • Changes are sent to all room participants via the existing WebSocket connection
  • The whiteboard is visible to all participants
  • Controlled by StageTypeConfig.toolsConfig.whiteboard

Screen Sharing

For live sessions where toolsConfig.screenShare: true:

  • Uses navigator.mediaDevices.getDisplayMedia() to capture screen
  • Screen track replaces (or adds alongside) the camera video track in the WebRTC connection
  • Visible to all participants in the room

Private Question Panel (Interviewer-Only)

The "My Questions" panel in the live room is only visible when:

  1. The user is authenticated (recruiter role)
  2. interview.stageTypeKey === 'live_1on1' or 'culture_fit_hr'

The panel fetches questions from GET /v1/interviews/:id/private-questions. This endpoint is auth-gated to the interviewer only. The interviewerHints and expectedAnswerGuide fields are returned to the interviewer but are never sent to the candidate's browser.

When the interviewer clicks "Push to candidate":

  • Socket event push_question emitted with { questionText } only
  • Candidate's screen shows a floating card with the question text
  • interviewerHints / expectedAnswerGuide never leave the interviewer's session

Tool Visibility Matrix

All tool panels are rendered or hidden based on StageTypeConfig.toolsConfig:

Toolautomated_screeningtechnical_dsatechnical_ai_assistedlive_1on1
whiteboard
ide
screenShare
audio
video
aiChatbot
webcamProctoring
voiceInterface

TIP

The frontend checks stageTypeConfig.toolsConfig.<tool> to decide whether to render each panel — not a hardcoded switch statement.