Skip to content

feat: presence sync engine integrations#40557

Merged
dionisio-bot[bot] merged 5 commits into
feat/presence-expiration-uifrom
feat/presence-sync-integrations
Jun 19, 2026
Merged

feat: presence sync engine integrations#40557
dionisio-bot[bot] merged 5 commits into
feat/presence-expiration-uifrom
feat/presence-sync-integrations

Conversation

@ricardogarim

@ricardogarim ricardogarim commented May 15, 2026

Copy link
Copy Markdown
Member

Proposed changes

Integrates the presence sync engine into calendar, voice call, and video conference services, replacing direct DB status updates with the unified Presence.setActiveState() / Presence.endActiveState() API.

How the integration works

Each source claims presence through the engine and tags its claim with a statusId, so it can later release exactly that claim:

  • Voice callsMediaCallService listens to callActivated / callEnded from CallDirector (new MediaCallServerEvents) and sets/clears a busy claim keyed by callId. Text "On a call", statusSource: 'internal' (highest priority).
  • Video conferences — sets a busy claim on join and clears it on conference end, keyed by the conference id. Text "In a meeting", statusSource: 'internal'.
  • Calendar — applies one merged claim per user ("busy until the latest active meeting ends"), keyed by 'calendar', statusSource: 'external'. The engine expires it via statusExpiresAt, so the scheduler only schedules event starts. This replaces the old applyStatusChange flow and previousStatus tracking (~550 lines + tests removed) and drops previousStatus from ICalendarEvent.

Why statusId

A user can hold two equal-priority internal claims at once (e.g. a voice call and a video conference). The engine stashes the displaced claim so it can be restored — but with only a statusSource to go on, endActiveState couldn't tell which claim was ending, so ending the older one first restored a stale claim over the still-active newer one.

Each claim now carries a statusId, so endActiveState(uid, statusId) removes the exact claim and restores correctly in any end order. It also makes a declined/never-active call a no-op (its id was never claimed), so it can't clobber a manual or calendar status. statusId is internal-only and excluded from client projections.

The Apps-Engine API also exposes statusId: an app can pass it in setActiveState's state and to endActiveState(userId, statusId?), so an app scopes and clears its own claim the same way.

Issue(s)

Steps to test or reproduce

See the use case matrix for the full set of scenarios.

Further comments

Depends on #40469 (frontend) and #40274 (backend engine).

Final PR in the stack: all presence writers (manual, calendar, voice, video) now go through the unified engine, and direct DB writes for status are fully eliminated.

Summary by CodeRabbit

  • New Features

    • Presence now drives busy states for calendar events, video conferences, and media calls with localized texts ("In a meeting", "On a call"). Each claim is tagged with an id so concurrent claims (e.g. a call and a conference) resolve correctly in any end order.
  • Bug Fixes

    • Concurrent busy claims no longer restore a stale status when they end out of order.
    • Immediate clearing of busy presence when deleting an in‑progress calendar event with no overlap.
    • Simplified calendar scheduler and more consistent presence resolution, including improved offline/no‑connection behavior.
  • Tests

    • Unit and end‑to‑end tests updated to reflect new presence and status flows; some legacy calendar status tests removed.

@dionisio-bot

dionisio-bot Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

Looks like this PR is ready to merge! 🎉
If you have any trouble, please check the PR guidelines

@changeset-bot

changeset-bot Bot commented May 15, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 894224b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The PR moves busy presence management to the Presence engine: calendar event starts set active BUSY presence with localized text and expiry; scheduler schedules only at the next future event start. Media-call and video-conference services set/clear BUSY presence on lifecycle events. Presence engine and tests updated for disconnected/service-user semantics and equal-priority claim handling.

Changes

Presence-driven busy status refactoring

Layer / File(s) Summary
Presence engine core and tests
ee/packages/presence/src/lib/presenceEngine.ts, ee/packages/presence/src/lib/presenceEngine.spec.ts, ee/packages/presence/src/Presence.ts
Adds disconnected-status logic, treats equal-priority setActive as replacing current claim (stored in previousState), narrows statusText persistence, expands processPresence typing, and extends tests for auto-away, same-priority, and no-connection service-user cases.
Calendar service presence integration & scheduler
apps/meteor/server/services/calendar/service.ts, apps/meteor/tests/unit/server/services/calendar/service.tests.ts, apps/meteor/tests/end-to-end/api/calendar.ts
Calendar schedules only calendar-status-scheduler at next future busy event start, sets active BUSY presence (localized text, expiry) on event start, ends active presence on delete only if no overlapping busy events remain, and test expectations updated accordingly.
Media-call contract, emissions, and service wiring
ee/packages/media-calls/src/definition/IMediaCallServer.ts, ee/packages/media-calls/src/server/CallDirector.ts, apps/meteor/server/services/media-call/service.ts
Adds callActivated/callEnded events and emissions; media-call service listens and sets/clears per-user BUSY presence with localized "on a call" text and per-user language resolution.
Video conference presence lifecycle
apps/meteor/server/services/video-conference/service.ts
Video conference resolves participant language on join, sets localized "in a meeting" BUSY active presence via Presence, and clears active presence for all participants on call end with per-user error logging.
Effective-status guards in user APIs
apps/meteor/app/api/server/v1/users.ts, apps/meteor/app/user-status/server/methods/setUserStatus.ts, apps/meteor/tests/end-to-end/api/users.ts
Derives effectiveStatus (request or user default), applies invisible-status restrictions against it, uses it for Presence.setStatus, and adds e2e test asserting message-only updates are rejected when invisible status is disabled.
Models, typings, and localization
packages/core-typings/src/ICalendarEvent.ts, packages/models/src/models/CalendarEvent.ts, packages/i18n/src/locales/en.i18n.json
Removes previousStatus from ICalendarEvent and CalendarEvent update/projections; adds English translations Presence_status_on_a_call and Presence_status_in_a_meeting.

Sequence Diagrams

sequenceDiagram
  participant Scheduler as Status Scheduler
  participant CalendarService
  participant Presence
  Scheduler->>CalendarService: processStatusChangesAtTime
  CalendarService->>Presence: setActiveState(event start, localized "in a meeting", statusExpiresAt=endTime)
  CalendarService->>Presence: endActiveState(uid) on delete if no overlapping busy
Loading
sequenceDiagram
  participant CallDirector
  participant MediaCallService
  participant Presence
  CallDirector->>MediaCallService: callActivated(callId, uids)
  MediaCallService->>Presence: setActiveState(BUSY, "On a call", per-user language)
  CallDirector->>MediaCallService: callEnded(callId, uids)
  MediaCallService->>Presence: endActiveState(uid)
Loading
sequenceDiagram
  participant VideoConfService
  participant Presence
  VideoConfService->>Presence: setActiveState(user join, language -> "In a meeting")
  VideoConfService->>Presence: endActiveState(call end for all users)
Loading

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers:

  • tassoevan
  • sampaiodiego
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat: presence sync engine integrations' accurately summarizes the main change: integrating the presence sync engine across calendar, media-call, and video-conference services.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (2)
  • PRES-26: Request failed with status code 401
  • PRES-27: Request failed with status code 401

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented May 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 68.75000% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.09%. Comparing base (acfffeb) to head (894224b).
⚠️ Report is 10 commits behind head on feat/presence-expiration-ui.

Additional details and impacted files

Impacted file tree graph

@@                       Coverage Diff                       @@
##           feat/presence-expiration-ui   #40557      +/-   ##
===============================================================
- Coverage                        70.12%   70.09%   -0.04%     
===============================================================
  Files                             3366     3362       -4     
  Lines                           130001   129959      -42     
  Branches                         22490    22469      -21     
===============================================================
- Hits                             91165    91090      -75     
- Misses                           35511    35554      +43     
+ Partials                          3325     3315      -10     
Flag Coverage Δ
unit 70.04% <78.37%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch from 807228e to a62ad69 Compare May 15, 2026 15:59
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from cbd523c to ef46ca9 Compare May 15, 2026 15:59
@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch from a62ad69 to 9ad1e60 Compare May 15, 2026 16:01
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from ef46ca9 to 64b2bb2 Compare May 15, 2026 16:01
@ricardogarim ricardogarim changed the title Feat/presence sync integrations feat: presence sync integrations May 15, 2026
@ricardogarim ricardogarim changed the title feat: presence sync integrations feat: presence sync engine integrations May 15, 2026
@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch from 9ad1e60 to c283812 Compare May 15, 2026 17:13
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch 3 times, most recently from 05b4e89 to 6e8cf4a Compare May 18, 2026 15:49
@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch from 75684ed to d29edd2 Compare May 18, 2026 16:09
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from 6e8cf4a to 5c1a902 Compare May 18, 2026 16:10
@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch from e88cee9 to c6ebe7e Compare May 19, 2026 17:31
@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch 3 times, most recently from 9c87407 to 7c0d0fd Compare June 5, 2026 23:13
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from 5c1a902 to 2111dc5 Compare June 8, 2026 12:11
@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch from 7c0d0fd to e83964f Compare June 8, 2026 15:47
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from 2111dc5 to 61e199f Compare June 8, 2026 15:54
@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch 3 times, most recently from 369da18 to b1043f4 Compare June 9, 2026 01:34
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from 61e199f to f24e992 Compare June 9, 2026 01:36
@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch from 718e76a to 3b25380 Compare June 16, 2026 21:00
@ricardogarim ricardogarim requested a review from a team as a code owner June 16, 2026 21:00
@ricardogarim ricardogarim force-pushed the feat/presence-expiration-ui branch from 3b25380 to 99020c3 Compare June 16, 2026 21:20
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from 2609433 to 1618513 Compare June 16, 2026 23:59
@ricardogarim ricardogarim removed the request for review from a team June 17, 2026 12:18
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch 3 times, most recently from ab67b49 to e09249b Compare June 17, 2026 16:44
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from e09249b to f06aa11 Compare June 19, 2026 02:18
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from f06aa11 to d320d36 Compare June 19, 2026 13:43
Comment thread apps/meteor/server/services/media-call/service.ts
Comment thread apps/meteor/tests/end-to-end/api/calendar.ts
Comment thread apps/meteor/server/services/calendar/service.ts
@ricardogarim ricardogarim force-pushed the feat/presence-sync-integrations branch from 338942b to d320d36 Compare June 19, 2026 20:55

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/meteor/server/services/media-call/service.ts">

<violation number="1" location="apps/meteor/server/services/media-call/service.ts:38">
P1: Presence updates for `callActivated` and `callEnded` can race, leaving users stuck as busy after quick call end. Serialize per-call presence transitions (or make activation/end idempotent with ordering guarantees) before writing claims.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread apps/meteor/server/services/media-call/service.ts
Comment thread packages/i18n/src/locales/en.i18n.json Outdated
@ricardogarim ricardogarim added the stat: QA assured Means it has been tested and approved by a company insider label Jun 19, 2026
@dionisio-bot dionisio-bot Bot added the stat: ready to merge PR tested and approved waiting for merge label Jun 19, 2026
@dionisio-bot dionisio-bot Bot merged commit bd244e1 into feat/presence-expiration-ui Jun 19, 2026
25 checks passed
@dionisio-bot dionisio-bot Bot deleted the feat/presence-sync-integrations branch June 19, 2026 22:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge type: feature Pull requests that introduces new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants