# Video Conferencing Module Phase 1: High-Level Design

Copy of the HLD emailed to Amit on 2 Nov 2026 (author: Arshdeep Singh). The live version with diagrams is the Claude doc shared with Amit; diagrams are described in text here.

**Summary.** HelixtaHR users start a video meeting from the Meetings menu without a second login. The meeting runs on our self-hosted LiveKit server, and our own Meetings backend enforces every rule: who gets in, who waits, who controls the meeting, and who is removed when HelixtaHR access ends. Phase 1 is for Rhysley companies and their employees only, and nothing is recorded. This document explains the design for review by Engineering, Product and QA, and ends with the decisions needed, each with a recommended answer.

## 1. Purpose and scope

Phase 1 gives HelixtaHR users secure video meetings without leaving HelixtaHR. It is built on unmodified LiveKit, with all business rules in our own backend, so EazeeSign and other products can reuse it later.

- **In Phase 1:** Rhysley companies and their employees only; instant meetings; a pre-join device check; audio, video, chat, one screen share at a time, raised hands and reactions; up to 25 devices per meeting; Host, Co-host and admission controls; audit records.
- **Phase 2 or later:** external guests, interviews and meetings scheduled from HelixtaHR, Permanent Meeting Rooms, background blur, recording, transcription and minutes.

## 2. How a meeting works

1. **Open Meetings** from the HelixtaHR menu, with no second login. Companies not enabled see "You don't have access to Meetings".
2. **Start meeting** opens the pre-join page: camera preview, microphone level, device choice, and help if the browser blocks a device. Nothing is created yet.
3. **Join now** creates the meeting and its audit record. The starter becomes Host, joins with the microphone on, and gets the link to share.
4. **Colleagues open the link,** pass the same pre-join check and select Join now. Unless they are Host or Co-host, they wait on a waiting screen, sending no audio or video.
5. **A Host, Co-host or Acting Host admits them.** They join with the microphone off and the camera as they chose.
6. **In the meeting,** people talk, chat, raise hands, react and share a screen one at a time. Hosts appoint Co-hosts, stop any share and lower any hand.
7. **If someone drops,** they can return within 2 minutes without new admission, muted. A host who leaves on purpose hands over first.
8. **End Meeting** disconnects everyone, and the link stops working.

## 3. Architecture

Three parts work together: the Meetings interface in the browser, our Meetings backend that holds every rule, and a self-hosted LiveKit server that carries audio and video. The browser reaches LiveKit only with a short-lived pass that our backend issues after every check passes.

Diagram (text form):
```
Employee's browser
  ├─ HelixtaHR web app (signed-in employee opens Meetings from the left menu)
  └─ Meetings interface (pre-join, waiting and meeting screens; LiveKit components)
        │ API calls with HelixtaHR token                 │ media and chat with meeting pass
        ▼                                                ▼
Meetings module backend (Python/FastAPI)            LiveKit server (self-hosted, unmodified,
  ├─ API and join checks (token, company,             TURN relay for strict networks)
  │   link, capacity)                                   ▲
  ├─ Admission and screen share (waiting room,          │ server API and room events
  │   share requests)  ─────────────────────────────────┘
  ├─ Audit records (every create, join, admit, end)
  └─ Re-check worker (user status at least every 4 minutes)
        │ status checks ↕ deactivation/role-change notices      │ records only
        ▼                                                        ▼
HelixtaHR backend (Laravel; HelixtaHR login)          Database (PostgreSQL; no media or chat)
```

## 4. Access and security

Signing in through HelixtaHR opens Meetings; it never admits anyone to a meeting.

- **Login:** the interface uses the user's existing HelixtaHR token, `ai_assist_jwt_token`, the same one Helix AI uses. The backend verifies it and takes user and company only from it. Someone not signed in is sent to the HelixtaHR sign-in page.
- **Meeting pass:** issued only at Join now or on admission; valid for one user, one company, one meeting and one device, and short-lived.
- **Company separation:** every query is filtered by the user's company, so users of another company can never see or join its meetings.
- **Company enablement:** only Rhysley companies, switched on by the Platform Administrator and enforced in the backend. Customer companies need Management approval.
- **Roles:** every user of an enabled company can use Meetings. HelixtaHR admin and superadmin also see the Settings tab.
- **Losing access:** when HelixtaHR deactivates a user, it notifies the module and the user is removed at once. If that notice fails, the module re-checks every user with HelixtaHR at least every 4 minutes, so removal always happens within 5 minutes. The user sees "You've been removed from the meeting".
- **Controls:** every action is authorised in the backend, all traffic is encrypted, secrets stay on company servers, and important actions are audited. Nothing said or shared is stored in Phase 1.

## 5. Meeting lifecycle

Following Management's direction on HEL-1026, a normal meeting has two controls, Leave and End Meeting, and End Meeting closes its link for good.

Diagram (text form):
```
[Instant meeting: created at Join now] --Join now--> [Session live: Host or Co-host connected;
                                                       others wait for admission]
                                                          │ End Meeting
                                                          ▼
                                                     [Ended: link no longer valid; nobody can rejoin]
During a session:                                    Variant (separate story, not Phase 1):
 - Host/Co-host leaving on purpose hands over first   [Permanent Meeting Room: End Meeting keeps
 - Unexpected drop of last host: Acting Host            room and URL; no Acting Host]
 - Reconnect within 2 min: no new admission, muted
 - Last person leaves without End Meeting: to be confirmed
```

- **Leave** disconnects only that person. The last Host or Co-host leaving on purpose must hand over first.
- **Unexpected drop** of the last host: the admitted employee present longest becomes Acting Host. The Host gets their rights back on return.
- **End Meeting** (Host, Co-host or Acting Host): everyone is disconnected, people waiting are released, and the link shows "This meeting link is no longer valid".
- Reusable links belong only to Permanent Meeting Rooms, a separate story outside Phase 1.

## 6. Joining and admission

At Join now the backend runs these checks in order. The first failure decides what the user sees, and no refusal reveals meeting details.

| Check | If it fails, the user sees |
| --- | --- |
| Signed in to HelixtaHR | The HelixtaHR sign-in page |
| Company enabled for Meetings | "You don't have access to Meetings" |
| Same company, and still active in HelixtaHR | "You can't join this meeting" |
| Link still valid | "This meeting link is no longer valid" |
| Fewer than 25 devices in the meeting | "This meeting is full" |
| LiveKit reachable | "Meetings are temporarily unavailable" (an alert is raised) |

If every check passes, the Host and Co-hosts connect directly and everyone else waits.

- People waiting are not connected to the meeting: they send and receive no audio, video or content, and don't count toward the 25.
- Only the Host, Co-hosts and Acting Host can admit or deny. If no host is present, people keep waiting.
- A dropped person's place is held for 2 minutes; after that they join as new.
- **Supported browsers:** Chrome, Edge, Firefox and Safari on desktop; iPhone Safari and Android Chrome; latest two versions. A busy or blocked camera or microphone shows "can't be used right now" with steps to fix it, and the user can always continue without it.

## 7. In the meeting

- **Chat** goes to everyone as plain text: links are not clickable, there are no files, and nothing is kept.
- **Screen sharing, one at a time:** if A is sharing and B selects Share, B picks a screen straight away (browsers require this) and A gets a request with Stop sharing, which the hosts also see. When A stops, B's share starts automatically. Hosts can stop any share.
- **Raised hands** are listed earliest first. Hosts see an indicator even while presenting and can lower any hand; the person is told.
- **Reactions:** five, shown briefly on the sender's video tile.
- **Host controls** (appoint Co-hosts, admit, stop shares, lower hands, End Meeting) are enforced in the backend, not just hidden in the interface.

## 8. HelixtaHR integration

Meetings connects to HelixtaHR the same way Helix AI already does: HelixtaHR's login (`POST /api/v1/login`) returns `ai_assist_jwt_token`, and services call HelixtaHR's `/api/v1/ai/...` endpoints with it, acting as the signed-in user.

Phase 1 needs three small changes in HelixtaHR:

| # | Change in HelixtaHR |
| --- | --- |
| H1 | A status endpoint in the same style (for example `GET /api/v1/ai/meetings/me`) returning the user's active status, company and role, called at every join and every re-check |
| H2 | A notice to the Meetings backend when a user is deactivated or their role changes |
| H3 | A Meetings item in the HelixtaHR left menu |

Moved to Phase 2: guest invitations, interviews and meetings scheduled from HelixtaHR, rescheduling, and events sent back to HelixtaHR.

## 9. Monitoring and quality

- **Monitoring:** automatic checks every minute on LiveKit, the backend, the database and HelixtaHR's status endpoint. After two failures in a row, alerts go to Amit and a second contact, with escalation if nobody responds.
- **Quality benchmarks** (internal QA targets set with Deepak, not guarantees): a microphone or camera change seen within 1 second, chat within 2 seconds, a screen share within 3 seconds, and at least 98% of joins succeeding. Delays caused by the application are defects; delays from a poor network are not.

## 10. Delivery

The nine approved stories are built in this order: HEL-1044, HEL-972, HEL-973, HEL-975, HEL-976, HEL-977, HEL-979, HEL-980, HEL-1032. HEL-1043 and HEL-1026 follow once decisions 1 to 5 below are made.

**Needed before coding starts:** a development LiveKit server with TURN; a HelixtaHR developer for H1 to H3; Ishank's designs for the waiting screen, share request, device states and browser steps; and story-level QA approval by Deepak.

## 11. Decisions needed

Each decision comes with a recommended answer, so it can simply be confirmed or changed. Decisions 1 to 5 release HEL-1026 and HEL-1043; the rest are needed before or during development.

| # | Decision | Recommendation | Decides |
| --- | --- | --- | --- |
| 1 | The last person leaves, or drops for over 2 minutes, without End Meeting | Treat it as End Meeting: the link becomes invalid | Management, Harsh |
| 2 | The last host leaves without handing over | Leave asks them to pick a successor or End Meeting | Harsh |
| 3 | Who can receive a handover | Any admitted employee in the meeting | Harsh |
| 4 | Ended meetings on the Meetings page | Shown as "Ended", with no Open or Copy link | Harsh |
| 5 | Phase for Permanent Meeting Rooms | Phase 2 | Management |
| 6 | What the Meetings page lists in Phase 1 | Instant meetings the user hosted, co-hosted or was admitted to, with date and time | Harsh |
| 7 | Rhysley company IDs for test and live, and who is Platform Administrator | To be named | Management, Amit |
| 8 | HelixtaHR unreachable during a meeting | People already in stay and are re-checked when it returns; new joins are refused | Amit |
| 9 | Someone not signed in opens a link | Sent to the HelixtaHR sign-in page; no new screen | Harsh |
| 10 | HelixtaHR developer for H1 to H3 | Surinder Chahal | Amit |
| 11 | How the interface sits in HelixtaHR | Its own Meetings app on a subdomain, shown inside HelixtaHR, so EazeeSign can reuse it | Amit |
| 12 | Stack and hosting | Python (FastAPI) and PostgreSQL; React with LiveKit components; LiveKit and TURN on company servers, with a named owner | Amit |
| 13 | Alert recipients | Amit plus a named second contact; email and team chat; escalation if unanswered | Amit |
| 14 | Several people ask to share a screen | One request at a time; it stays until the requester cancels or the presenter responds | Harsh |
| 15 | Speaker choice on browsers that can't (iPhone Safari) | Hide the speaker list; the test sound plays through the default speaker | Amit, Harsh |
| 16 | Admitted guests copying the link (HEL-979) | Moves to Phase 2 with guests | Harsh, Deepak |
| 17 | How long meeting records are kept | Set with the organisation settings (Epic 7) | Harsh |
| 18 | Same login token shared with Helix AI | Fine for Phase 1; add an audience claim before other products connect | Amit |
