feat: realtime work-item updates over the live server (auto-refresh boards/lists) - #9780
feat: realtime work-item updates over the live server (auto-refresh boards/lists)#9780Liewzheng wants to merge 1 commit into
Conversation
…E-22) - api: broadcast issue change events from the issue_activity celery task (plus bulk delete) to the live server via a shared-key internal endpoint - live: new POST /broadcasts/issue-events controller relaying events to the issue-events:<project_id> hocuspocus channel over Redis; database and title-sync extensions skip the ephemeral channel namespace - web: useIssueRealtime hook subscribes from the project layout root and soft-refreshes issues (no loader flash) on remote changes, debounced - disabled unless LIVE_INTERNAL_API_KEY is set on api/worker and live
◈ PR Lens
Architecture 10 components touched across 4 lanes. Inside the changed components — 2 viewsComponent view — Live collaboration server broadcast pipeline The internal controller, Redis pub/sub dispatcher, and extension overrides handling ephemeral issue events. Component view — Web client realtime subscription The React layout integration and Hocuspocus provider hook that listens for remote issue mutations. Data flow
Drill down
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
Description
Work-item views (kanban/list/calendar/gantt/spreadsheet) are fetch-on-mount today: when a teammate drags a card, edits an item, or a CI bot changes state through the v1 API, everyone else's screen stays stale until a manual reload. This PR adds realtime work-item updates by reusing the live (collaboration) server that already ships with CE for pages — no new realtime stack.
Flow:
API write → issue_activity celery task → POST /broadcasts/issue-events (shared key) → live server relays to issue-events:<project_id> over Redis → subscribed web clients soft-refetch with existing pagination.API (
apps/api):plane/utils/issue_events.py: fire-and-forgetbroadcast_issue_event()— POSTs{project_id, issue_id, type, actor_id}(metadata only, no work-item data) to the live server with anx-internal-api-keyheader, 2s timeout, failure logs a warning and never breaks the request/task.issue_activitytask, which covers detail edits, drag & drop (state/sort), creation, deletion, archiving, cycle/module membership, links/attachments/relations and API-token-driven changes.BulkDeleteIssuesEndpoint(which bypasses activity logging) emits explicitly.LIVE_INTERNAL_API_KEYis set (new optional env, empty by default → zero behavior change).Live server (
apps/live):POST /broadcasts/issue-eventscontroller: shared-key auth (401/400 on bad requests), relays the payload with the existing Redis extension'sbroadcastToDocument(multi-instance safe).databaseandtitle-syncextensions guard the ephemeralissue-events:document namespace (no page fetches/writes for these channels).Web (
apps/web):useIssueRealtime(projectId, onEvent)hook: HocuspocusProvider subscribed to the project channel (same URL construction and cookie auth as the page editor), parses stateless events, ignores events caused by the current user, debounces bursts (500ms), then callsfetchIssuesWithExistingPagination— a background soft refresh with no loader flash.project-layout-root, covering all five project work-item layouts.Type of Change
Test Scenarios
check:typespasses forliveandweb; lint/format clean;py_compileon changed API modules.Published to issue-events:<project>, 1 subscribers; endpoint returns 401 without / 200 with the shared key.LIVE_INTERNAL_API_KEYunset (default), the broadcast path is fully inert.References