Subhaprasad.com – FIFA World Cup UpdatesAll match times shown in IST (UTC+5:30)
All case studies

Real-Time Web Application

Real-Time Collaborative Planning Platform

A secure offline-aware planning web app with live presence, conflict-safe board updates, comments, sprint analytics, and resilient team synchronization.

Collaborative project board with live cursors, team presence, sprint progress, task cards, and activity feed

Project overview

Distributed product teams needed a planning workspace that felt immediate during sprint meetings but remained dependable on unstable connections. Their previous board required manual refreshes, silently overwrote simultaneous edits, and showed activity only after a full page load. I led development of a real-time planning application with boards, tasks, comments, presence, activity history, sprint reporting, and offline-aware updates.

The challenge was not merely opening a WebSocket. The product needed explicit consistency rules, scalable fan-out, understandable conflicts, and a durable event history behind the live interface.

Problem statement

During active planning sessions, several people moved and edited cards at once. Last-write-wins behavior could erase a longer description with a stale browser copy. Reordering dozens of cards produced large writes, and temporary disconnections made the board appear successful before changes later disappeared.

The replacement needed low perceived latency, stable ordering, tenant isolation, graceful reconnect, and activity that users could trust as an audit of meaningful changes.

Real-time architecture

Next.js rendered the initial project and board state, then a Node.js WebSocket gateway subscribed each authorized client to tenant and project channels. MongoDB stored canonical task state and an append-only activity stream. Redis pub/sub distributed accepted events between gateway instances and tracked short-lived presence.

The client applied optimistic updates with a mutation identifier and expected entity version. The server validated permissions and version, committed the change, and broadcast the canonical result. Conflicts returned the latest entity plus fields that differed, allowing the interface to preserve the user's draft rather than discard it.

socket.emit("task:update", {
  mutationId: crypto.randomUUID(),
  taskId,
  expectedVersion: task.version,
  patch: { status: "review" },
});

Fractional position keys allowed cards to move without rewriting every sibling. A background compaction job occasionally normalized keys. Comments and descriptions used field-level version checks; collaborative cursors and presence remained ephemeral and never entered the durable audit stream.

Resilience and product details

  • Reconnect resumed from the last acknowledged event sequence.
  • Offline mutations were queued locally and visibly marked as pending.
  • Duplicate mutation IDs returned the original result instead of writing twice.
  • Presence expired automatically when heartbeats stopped.
  • Activity entries summarized human actions rather than infrastructure events.
  • Permissions were rechecked for every mutation, not only at connection time.
  • Keyboard-accessible drag controls provided an alternative to pointer movement.

Load tests simulated meeting bursts, reconnect storms, and large project rooms. Metrics tracked broadcast latency, rejected versions, replay depth, connected clients, and Redis queue pressure. Playwright multi-page tests verified that accepted changes appeared consistently across clients.

Outcomes

Median accepted-change-to-broadcast latency measured 180 ms in the primary deployment region. Version checks and conflict recovery reduced reported lost or conflicting edits by 43%. Teams completed sprint-planning sessions 29% faster, helped by live presence, immediate updates, and shared filters.

The offline queue also made failure honest: users could see when changes were pending and retry or resolve them after reconnect. Separating ephemeral presence from durable business events kept storage and activity history focused while still delivering a lively collaborative experience.

Key engineering decisions

The system did not apply one conflict strategy to every field. Status and assignee changes used optimistic version checks; descriptions preserved a recoverable draft when versions diverged; reactions and watchers used commutative set operations. This smaller, domain-specific approach was easier to test and explain than introducing a general collaborative document algorithm for the whole product.

WebSocket authorization was short-lived. Connections periodically refreshed claims, and project membership changes invalidated affected subscriptions through Redis. The gateway never trusted a channel name supplied by the browser without resolving membership. Backpressure limits dropped disposable cursor events before durable task changes, keeping core collaboration responsive during bursts. Event payloads carried schema versions, enabling rolling deployments where old and new gateway instances briefly coexisted. These boundaries turned real-time behavior into an observable delivery channel rather than a second, less secure application API.

Related engineering work

The interface system shares principles with the online learning UI/UX redesign. For application and deployment patterns, see the future of full-stack development and serverless computing trends.