Skip to content

improvement(sockets): position persistence on drag end, perms call only on joining room#1571

Merged
icecrasher321 merged 1 commit intostagingfrom
improvement/sockets-optimization
Oct 8, 2025
Merged

improvement(sockets): position persistence on drag end, perms call only on joining room#1571
icecrasher321 merged 1 commit intostagingfrom
improvement/sockets-optimization

Conversation

@icecrasher321
Copy link
Collaborator

Summary

  • Persist position update only on drag end
  • Make permissions check only on room join to reduce number of db calls

Type of Change

  • Other: Performance Improvement

Testing

Tested by observing sockets server logs

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)

@vercel
Copy link

vercel bot commented Oct 8, 2025

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

Project Deployment Preview Comments Updated (UTC)
sim Ready Ready Preview Comment Oct 8, 2025 0:25am
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
docs Skipped Skipped Oct 8, 2025 0:25am

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Summary

This PR implements performance optimizations for the real-time collaborative workflow editor by addressing two key areas: position update persistence and permission checking. The changes introduce a commit-based system for position updates where intermediate drag movements are broadcast for real-time collaboration but only persisted to the database when the drag operation completes. Additionally, the permission system has been refactored to cache user roles during room join and use synchronous role-based checks instead of repeated database queries.

The implementation spans multiple layers of the application: the frontend workflow editor now sends position updates with a commit flag (false during drag, true on drag end), the socket server differentiates between broadcast-only and persistent operations, and the database operations layer only writes to the database when explicitly committed. For permissions, the socket server now stores user roles in the presence data structure when users join rooms, enabling fast role-based permission checks using a static configuration instead of database queries.

These changes integrate well with the existing collaborative architecture by maintaining the real-time experience while reducing database load. The commit pattern aligns with established workflow patterns like undo/redo operations, and the role caching mechanism leverages the existing presence management system in the socket server.

Important Files Changed

Changed Files
Filename Score Overview
apps/sim/socket-server/rooms/manager.ts 5/5 Added role field to UserPresence interface for caching user permissions
apps/sim/socket-server/validation/schemas.ts 5/5 Added optional commit field to BlockOperationSchema for position persistence control
apps/sim/socket-server/database/operations.ts 5/5 Added condition to only persist position updates when commit flag is true
apps/sim/hooks/use-undo-redo.ts 5/5 Added commit:true parameter to position updates in undo/redo operations
apps/sim/contexts/socket-context.tsx 4/5 Implemented commit-based position update throttling with immediate send on commit
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx 5/5 Modified drag handlers to send non-committed updates during drag and committed updates on drag end
apps/sim/socket-server/middleware/permissions.ts 4/5 Refactored permissions to use static role-based checks instead of database queries
apps/sim/socket-server/handlers/workflow.ts 3/5 Added role caching during room join but inconsistent permission handling in request-sync
apps/sim/socket-server/index.test.ts 4/5 Updated tests to reflect new synchronous permission checking and role caching
apps/sim/socket-server/handlers/operations.ts 4/5 Implemented early returns for non-committed position updates and role-based permission checks
apps/sim/hooks/use-collaborative-workflow.ts 4/5 Added commit parameter to position updates with conditional queuing logic

Confidence score: 4/5

  • This PR implements well-architected performance optimizations that should significantly reduce database load during collaborative editing
  • Score reflects solid implementation with minor inconsistencies in permission handling and some complexity in the throttling logic
  • Pay close attention to apps/sim/socket-server/handlers/workflow.ts for the inconsistent permission check in request-sync handler

Sequence Diagram

sequenceDiagram
    participant User
    participant WorkflowComponent as Workflow Component
    participant ReactFlow
    participant CollaborativeWorkflow as Collaborative Hook
    participant SocketContext as Socket Context
    participant SocketServer as Socket Server
    participant Database

    User->>WorkflowComponent: "Drag block from toolbar"
    WorkflowComponent->>WorkflowComponent: "onDragStart: Generate block data"
    
    User->>ReactFlow: "Drag over canvas"
    ReactFlow->>WorkflowComponent: "onDragOver event"
    WorkflowComponent->>WorkflowComponent: "Calculate position & check container intersection"
    WorkflowComponent->>WorkflowComponent: "Highlight drop zones"
    
    User->>ReactFlow: "Drop block on canvas"
    ReactFlow->>WorkflowComponent: "onDrop event"
    WorkflowComponent->>WorkflowComponent: "preventDefault() & parse drag data"
    WorkflowComponent->>WorkflowComponent: "Calculate final position from mouse coordinates"
    WorkflowComponent->>WorkflowComponent: "Generate unique ID and name"
    WorkflowComponent->>WorkflowComponent: "Check for auto-connect (findClosestOutput)"
    
    alt Auto-connect enabled and closest block found
        WorkflowComponent->>WorkflowComponent: "determineSourceHandle() for closest block"
        WorkflowComponent->>WorkflowComponent: "Create auto-connect edge"
    end
    
    WorkflowComponent->>CollaborativeWorkflow: "collaborativeAddBlock(id, type, name, position, ...)"
    CollaborativeWorkflow->>CollaborativeWorkflow: "Generate block config & subBlocks"
    CollaborativeWorkflow->>CollaborativeWorkflow: "Add to operation queue"
    CollaborativeWorkflow->>WorkflowComponent: "Apply locally (immediate UI feedback)"
    WorkflowComponent->>ReactFlow: "Update nodes state"
    ReactFlow->>User: "Block appears on canvas"
    
    CollaborativeWorkflow->>SocketContext: "emitWorkflowOperation('add', 'block', payload)"
    SocketContext->>SocketServer: "workflow-operation event"
    SocketServer->>SocketServer: "Validate permissions & operation"
    SocketServer->>Database: "persistWorkflowOperation()"
    
    par Persist to database
        Database->>Database: "INSERT into workflowBlocks"
        alt Auto-connect edge present
            Database->>Database: "INSERT into workflowEdges"
        end
        Database->>SocketServer: "Success confirmation"
    and Broadcast to collaborators
        SocketServer->>SocketContext: "Broadcast to other users in room"
        SocketContext->>CollaborativeWorkflow: "Apply remote operation"
        CollaborativeWorkflow->>WorkflowComponent: "Update local state"
        WorkflowComponent->>ReactFlow: "Update nodes for collaborators"
    end
    
    SocketServer->>SocketContext: "operation-confirmed event"
    SocketContext->>CollaborativeWorkflow: "Confirm operation in queue"
    CollaborativeWorkflow->>CollaborativeWorkflow: "Remove from pending operations"
    
    Note over User,Database: Block successfully added and synced across all collaborators
Loading

Additional Comments (1)

  1. apps/sim/socket-server/handlers/workflow.ts, line 123-127 (link)

    logic: This permission check contradicts the PR's goal of reducing DB calls. Consider using the cached role from the room's UserPresence instead of calling verifyWorkflowAccess again.

11 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile


// Apply light throttling only to position updates for smooth collaborative experience
const isPositionUpdate = operation === 'update-position' && target === 'block'
const { commit = true } = payload || {}
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: Default value commit = true seems incorrect - should default to false to maintain throttling behavior for intermediate updates

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/contexts/socket-context.tsx
Line: 603:603

Comment:
**logic:** Default value `commit = true` seems incorrect - should default to `false` to maintain throttling behavior for intermediate updates

How can I resolve this? If you propose a fix, please make it concise.

role: string,
operation: string
): { allowed: boolean; reason?: string } {
const allowedOperations = ROLE_PERMISSIONS[role] || []
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Consider adding validation for unknown roles - empty array fallback could allow all operations to be denied silently, which might be confusing during debugging

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/socket-server/middleware/permissions.ts
Line: 47:47

Comment:
**style:** Consider adding validation for unknown roles - empty array fallback could allow all operations to be denied silently, which might be confusing during debugging

How can I resolve this? If you propose a fix, please make it concise.

@icecrasher321 icecrasher321 merged commit 8e43774 into staging Oct 8, 2025
10 checks passed
@waleedlatif1 waleedlatif1 deleted the improvement/sockets-optimization branch October 13, 2025 17:38
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