CRM that bridges two worlds without breaking either

CRM that bridges two worlds without breaking either

The client had outgrown their project management setup. Their main SEO platform tracked migrations, chains, journals, and analytics — but it had no concept of client relationships, deal stages, or team workflows. They'd been using a third-party project management tool for that, but it was disconnected from their operational data. An operator would check the SEO platform for technical status, then switch to the project tool for client context, then copy numbers between them manually. The ask was a CRM that lives alongside their platform — same ecosystem, shared data, but its own space for relationship management.

standalone app and proxy

Kanban board with cards showing linked migration chain status

We built it as a standalone application with its own codebase and its own database. This was a deliberate architectural choice. The main SEO platform's database schema was already complex and tightly coupled — bolting CRM tables onto it would have created a maintenance nightmare. Instead, the CRM connects to the main platform through proxy API routes. When an operator opens a card, the CRM fetches the associated migration chain, journal entries, analytics data, and webmaster errors from the main platform in real time. The CRM's own database handles boards, cards, comments, stickers, and user preferences — everything that's CRM-specific.

board and virtualization

The board interface is a Kanban system built around drag-and-drop with @dnd-kit. Cards move between columns, columns represent deal stages, and every move is persisted immediately. We added comments with threading, color-coded stickers for quick visual categorization, and a search system that indexes card titles, descriptions, and comment text. For boards with hundreds of cards, we implemented virtualized rendering with @tanstack/react-virtual — only cards visible in the viewport are in the DOM, which keeps the interface responsive even when a board grows past a thousand items. Archive functionality lets operators clean up completed work without losing history.

realtime with socket.io

card detail view with comments, stickers, and linked platform data

Real-time updates via Socket.IO were essential — multiple operators work the same boards simultaneously, and stale state leads to conflicts. When one operator moves a card, every other operator on that board sees it move instantly. Comments appear as they're posted. Sticker changes propagate without refresh. The implementation required sticky sessions on the deployment side, since Socket.IO connections need to maintain affinity with the server instance that holds their state. Reconnection handling was equally important — network blips are common, and the client drops a WebSocket connection roughly once every few hours. The system detects disconnection, queues missed events, and replays them on reconnect so nothing is lost.

migration and platform bridge

The most unusual piece of work was the YouGile import. The client's previous project management data lived in YouGile, and they needed it in the new CRM. The data models had almost nothing in common — YouGile organizes around projects and tasks with subtasks, while our CRM uses boards with flat card lists. We wrote a one-time migration script that mapped YouGile projects to CRM boards, tasks to cards, subtasks to checklist items within cards, and comments to comments. Attachments were downloaded and re-uploaded. The mapping wasn't perfect — some structural information was lost in translation — but the client accepted the tradeoffs after reviewing a test migration of their smallest project.

The proxy architecture that connects the CRM to the main platform introduced its own complexity. API routes in the CRM forward requests to the main platform's endpoints, transforming responses to match what the CRM frontend expects. Authentication flows through both systems — the CRM issues its own JWT tokens via jose, but validates them against the main platform's user records. If the main platform is down or slow, the CRM still functions for its own data — cards, comments, board management all work independently. Only the overlay data (chains, migrations, analytics) shows a loading state until the main platform responds.

results

The result is a CRM that gives operators a single workspace for both relationship management and technical operations. Dashboard views built with Recharts surface metrics that previously required switching between three tools — deal pipeline value, migration completion rates, and client health scores all on one screen. The honest lesson from this project: building a bridge between two systems is harder than building either system alone. Every assumption one system makes about data shape, timing, and availability becomes a contract the other system has to honor — and those contracts break in subtle ways that only show up under real usage.

Stack

Frontend: Next.js 14, Radix UI, @dnd-kit (drag-and-drop), @tanstack/react-virtual, Recharts

Backend & API: Next.js 14 (Route Handlers), Prisma, PostgreSQL (separate database)

Real-time: Socket.IO (sticky sessions, reconnection queue)

Auth: jose (JWT generation and validation)

Integration: proxy routes to main SEO platform API

2026, «VOSGLOS». All rights reserved.