Case Study

Real-time Kanban task board for clinical teams, a technical case study

Building a real-time, multi-user Kanban board for clinic operations with optimistic drag-drop, Socket.io sync, and rollback on failure.

Clinic operations teams juggle a lot at once. Front desk needs to know which insurance verifications are pending. Billing needs to track which claims are stuck. Generic project tools like Jira or Trello technically work, but they don't sync fast enough for a busy clinic floor, and they don't understand clinic roles or permissions.

I built a Kanban board into Synectus Medico specifically for this, with one requirement that shaped the whole build: when someone moves a card, every other staff member looking at that board needs to see it move too, instantly, not after a page refresh.

Every client sees every move, instantly

To Do

Insurance verification: J. Kwan
Scan intake forms

In Progress

Follow up: pending cheque #4471

Done

Reschedule: Dr. Osei 2pm
LOP sent: attorney Reyes

The business problem

Clinical operations teams need shared task visibility across departments, but generic task tools lack real-time sync fast enough for a fast-paced clinic environment, and they don't respect the clinic's existing role and permission structure.

The solution

A Redux-backed Kanban board using entity adapters for normalized state, Atlaskit's pragmatic-drag-and-drop for the interaction layer, and Socket.io for real-time multi-user sync. Card moves update the local UI instantly, sync to the server, and broadcast to every other connected client on that board.

Why optimistic updates, and how rollback works

Waiting for a server round-trip before updating the UI makes drag-and-drop feel sluggish. So a card move updates the Redux store immediately, before the API call even resolves.

If the API call fails, the store rolls back to the pre-move state and the card snaps back to where it was. Without rollback, a failed API call would leave the UI showing a state that doesn't match the database.

Normalized Redux state with entity adapters

The Kanban slice is genuinely large, columns, cards, assignees, tags, all cross-referenced. Using Redux Toolkit's entity adapters kept this manageable: cards are stored as a normalized ids-and-entities structure rather than nested arrays, which makes moving a card between columns a fast, predictable update.

The slice runs to roughly 1,300 lines, handling card CRUD, column management, drag state, real-time sync reconciliation, and optimistic rollback all in one place.

Socket.io for real-time sync across users

When staff member A moves a card, the API confirms the move and broadcasts a socket event scoped to that clinic's board. Staff member B, viewing the same board, receives that event and applies the same move locally, no polling, no refresh needed.

The tricky part isn't broadcasting the event, it's reconciling it against a client's own optimistic state if that same client happens to be mid-update when the event arrives.

Card features and role-based access

  • Title, description, assignee, tags, priority (Low, Medium, High, Critical), due date
  • Attachment support for over 50 file types (insurance forms, signed authorizations, scanned IDs)
  • Board access plugs into the clinic’s existing role and permission model, no parallel access-control logic
  • Columns are configured per clinic, not hardcoded, and are themselves drag-reorderable

Debugging real-time sync issues in production

Worth being honest about this part, real-time systems are genuinely harder to debug than request-response APIs. The hardest bugs weren't in the happy path, they were edge cases like a connection dropping mid-drag, or two users moving the same card to different columns within the same second.

The approach that worked: every socket event carries a version number tied to the card's last-known state. If an incoming update's version doesn't match what the client expects, the client refetches that specific card from the API rather than trying to merge conflicting states client-side. Less elegant, dramatically more reliable.

Outcomes

A board where a card move by one staff member appears on every other connected staff member's screen within the round-trip time of a single API call, with optimistic UI keeping the interaction feeling instant regardless of network latency, and automatic rollback if a move actually fails server-side.

FAQ

Conclusion

The technical challenge in a real-time Kanban board isn't the drag-and-drop interaction itself. It's making optimistic updates, server confirmation, and multi-user real-time sync all agree with each other without the UI ever showing a state that doesn't match reality.

Building something similar?

Book a free 30-minute discovery call. No pitch, just a conversation about what you are building and how to approach it right.

Start the Conversation