Skip to content

feat(realtime): live workspace tables list, sharing one invalidation-room impl - #6053

Merged
waleedlatif1 merged 3 commits into
realtime-roomsfrom
workspace-tables-live
Jul 29, 2026
Merged

feat(realtime): live workspace tables list, sharing one invalidation-room impl#6053
waleedlatif1 merged 3 commits into
realtime-roomsfrom
workspace-tables-live

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

Brings the tables list to parity with the files list: a create/rename/move/delete/restore now propagates to every viewer live, instead of waiting out the 30s staleTime. Following the files pattern — but the honest, non-hacky version factors the two into one shared implementation rather than leaving two ~150-line copies.

  • Shared core, no duplication. Extracted setupWorkspaceInvalidationRoom (server) and useWorkspaceInvalidationRoom (client) — the presence-free, workspace-scoped live-list room. Files and tables now both bind to it, so they can't drift; event and room names derive from the room type. This replaces the standalone workspace-files handler + hook (net: the refactor is less code than the pre-existing files-only version plus a tables copy would have been).
  • ROOM_TYPES.WORKSPACE_TABLES + its authz resolver (workspace-id-addressed, reuses the workspace resolver like workspace-files).
  • Fan-out from the table service, not the routes: notifyWorkspaceTablesChanged fires from createTable/renameTable/moveTableToFolder/deleteTable/restoreTable, so it covers both the HTTP routes and copilot (which calls the service directly). Each call is gated on a genuine mutation.
  • Relay /api/workspace-tables-changed endpoint; hook wired into the tables page.
  • No presence, by request — this is list invalidation only. Live cell-selection stays in the per-table room.

Scope note: table folder create/rename/delete goes through the shared generic folders API and is a clean, separate follow-up (table CRUD — including moves — is fully covered here).

Type of Change

  • New feature

Testing

Tested manually. Consolidated the handler test into one suite run against both room types (files + tables), so the shared impl is covered for each. Full gate suite green: realtime + sim typecheck, realtime 235 tests, sim files/tables/hooks/table-service 1180 tests, api-validation, monorepo-boundaries, realtime-prune, lint.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…room impl

Bring the tables list to parity with the files list: a create/rename/move/delete/
restore now propagates to every viewer live instead of waiting out the 30s
staleTime. Following the files pattern, but factoring the two into one shared
implementation rather than copy-pasting.

- add ROOM_TYPES.WORKSPACE_TABLES + its authz resolver (workspace-id-addressed,
  reuses the workspace resolver like workspace-files)
- extract setupWorkspaceInvalidationRoom (server) and useWorkspaceInvalidationRoom
  (client) — the presence-free, workspace-scoped live-list room; files and tables
  now both bind to it, so they can never drift. Event/room names derive from the
  room type. Replaces the standalone workspace-files handler + hook
- notifyWorkspaceTablesChanged fanout fired from the table service (createTable,
  renameTable, moveTableToFolder, deleteTable, restoreTable) so it covers both the
  HTTP routes AND copilot, which call the service directly
- relay /api/workspace-tables-changed endpoint; wire the hook into the tables page
- consolidate the handler test into one suite run against both room types
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 29, 2026 5:41pm

Request Review

@cursor

cursor Bot commented Jul 29, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches realtime join/auth paths and mutation-side notify hooks; behavior is best-effort and gated on genuine mutations, but incorrect notify/join logic could cause stale lists or extra relay load.

Overview
Adds live invalidation for the workspace tables browser (same lossy workspace-tables-changed → refetch pattern as files), and deduplicates the files-only realtime/client code into shared setupWorkspaceInvalidationRoom / useWorkspaceInvalidationRoom, wired for both WORKSPACE_FILES and new WORKSPACE_TABLES (join/leave events and room names derived from room type).

Server fan-out: notifyWorkspaceTablesChanged posts to relay /api/workspace-tables-changed; table service calls it on create/rename/move/archive/restore. Table folder lifecycle uses notifyFolderResourceChanged; folder cascades pass skipNotify on per-table archive/restore so one folder-level notify covers the subtree.

Client: tables page uses useWorkspaceTablesRoom, invalidating table list and table-folder queries on change. Handler tests run the same suite against both room types so files and tables cannot drift.

Reviewed by Cursor Bugbot for commit 0f13492. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds live workspace tables-list invalidation by sharing one presence-free invalidation-room implementation with workspace files.

  • Introduces ROOM_TYPES.WORKSPACE_TABLES plus authz resolver and HTTP fan-out /api/workspace-tables-changed.
  • Extracts shared setupWorkspaceInvalidationRoom / useWorkspaceInvalidationRoom; files and tables bind to it.
  • Notifies from table service mutations and folder lifecycle (with cascade skipNotify), and wires the tables page hook.

Confidence Score: 5/5

This PR appears safe to merge; no blocking failures remain from prior or new eligible follow-up findings.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/realtime/src/handlers/workspace-invalidation-room.ts Generalized workspace-files join/leave into a shared presence-free invalidation room parameterized by room type.
apps/sim/lib/table/service.ts Fans out table-list invalidation after create/rename/move/delete/restore, with skipNotify for folder cascades.
apps/sim/lib/folders/lifecycle.ts Notifies table live-list on folder CRUD/restore via notifyFolderResourceChanged.
apps/sim/app/workspace/[workspaceId]/hooks/use-workspace-invalidation-room.ts Shared client join/retry/leave and onChanged invalidation for files and tables rooms.
apps/realtime/src/routes/http.ts Adds workspace-tables-changed internal relay endpoint mirroring workspace-files-changed.

Sequence Diagram

sequenceDiagram
  participant UI as Tables UI
  participant Hook as useWorkspaceTablesRoom
  participant RT as Realtime socket
  participant Svc as table/folder service
  participant HTTP as /api/workspace-tables-changed

  UI->>Hook: mount (workspaceId)
  Hook->>RT: join-workspace-tables
  Svc->>HTTP: notifyWorkspaceTablesChanged
  HTTP->>RT: emit workspace-tables-changed
  RT->>Hook: workspace-tables-changed
  Hook->>UI: invalidate table + folder queries
Loading

Reviews (3): Last reviewed commit: "fix(realtime): skip per-table live-list ..." | Re-trigger Greptile

Fold in the follow-up: a table folder create/rename/move/delete/restore now
propagates to the tables list live too, so the browser is fully consistent.

- generic notifyFolderResourceChanged(resourceType, workspaceId) dispatches the
  workspace live-list signal by resource type (a map, not a special-case if), so
  file/knowledge_base/workflow are no-ops today and gain liveness by adding a map
  entry when they adopt an invalidation room
- fired from the shared folder lifecycle (createFolder/updateFolder/deleteFolder/
  restoreFolder), covering routes AND copilot
- the tables room hook now invalidates the table folders query too, not just the
  tables list, since the page renders both
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/lib/table/service.ts Outdated
A folder delete/restore already fires one folder-level notifyFolderResourceChanged
for the whole subtree, but the cascade also calls deleteTable/restoreTable per
table — each awaiting its own notifyWorkspaceTablesChanged. A folder with many
tables would run N+1 sequential relay calls (each bounded by NOTIFY_TIMEOUT_MS),
blocking the mutation. Add a skipNotify option the cascade passes so only the one
folder-level notify fires.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 0f13492. Configure here.

@waleedlatif1
waleedlatif1 merged commit 4419951 into realtime-rooms Jul 29, 2026
4 checks passed
@waleedlatif1
waleedlatif1 deleted the workspace-tables-live branch July 29, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant