A real-time recruitment dashboard connecting NGO coordinators, passive job seekers, and companies — built with a WebSocket server, RxJS event pipeline, and TanStack Query for zero-polling live cache updates.

There is talent everywhere — in rooms that don't make the news, in CVs that never reach the right desk. For job seekers navigating an unfamiliar labour market, the gap between ability and opportunity is invisible to the coordinators trying to close it. Stage changes got lost in email threads. Company feedback arrived days late. Each delay was someone's chance at a fresh start slipping away.
A persistent WS connection makes stage updates feel instant — no refresh, no lag. Polling would have added 3–10 seconds of delay on every change; for a coordinator tracking dozens of live candidates, that cost compounds fast.
The WS server emits events every few seconds. Without processing, the same candidate_updated event could trigger multiple redundant re-renders. An RxJS Subject with a bounded dedup Set and 200ms buffer window ensures each UI update is meaningful and coalesced by entity.
Rather than maintaining separate local state, all realtime events patch the TanStack Query cache directly via setQueryData. Components read only from the cache — they re-render automatically and stay consistent even when the WS connection drops and reconnects.
Coordinators and companies need to see fundamentally different views of the same data. Auth0 roles embedded in the access token gate what each session can read — coordinators see all candidates across campaigns; companies see only candidates shared with them.
A working real-time prototype demonstrating the full pipeline: WebSocket server → RxJS dedup/batch stream → TanStack Query cache → instant UI updates, with Auth0 role-based access for coordinators and companies.