# Task 11: Integrate SignalR Real-time Updates **Task ID**: TASK-011 | **Story**: [STORY-003](sprint_1_story_3.md) | **Sprint**: [Sprint 1](sprint_1.md) **Estimated Hours**: 3h | **Assignee**: Frontend Developer 1 | **Priority**: P1 | **Status**: Not Started ## Task Description Connect Kanban board to SignalR event handlers for real-time updates when Epic/Story/Task changes occur. ## Implementation ### Update KanbanBoard.tsx (2h) ```typescript import { useEffect } from 'react'; import { useSignalRContext } from '../services/signalr/SignalRContext'; import { useQueryClient } from '@tanstack/react-query'; export const KanbanBoard: React.FC = () => { const { projectId } = useParams(); const queryClient = useQueryClient(); const { service, isConnected } = useSignalRContext(); // Subscribe to real-time events useEffect(() => { if (!isConnected || !service) return; const handlers = service.getEventHandlers(); if (!handlers) return; // Epic events const unsubEpicCreated = handlers.subscribe('epic:created', (event) => { queryClient.invalidateQueries(['epics', projectId]); }); const unsubEpicUpdated = handlers.subscribe('epic:updated', (event) => { queryClient.setQueryData(['epics', projectId], (old: Epic[]) => { return old.map(e => e.id === event.epicId ? { ...e, ...event } : e); }); }); const unsubEpicDeleted = handlers.subscribe('epic:deleted', (event) => { queryClient.setQueryData(['epics', projectId], (old: Epic[]) => { return old.filter(e => e.id !== event.epicId); }); }); // Story events (similar) const unsubStoryCreated = handlers.subscribe('story:created', (event) => { queryClient.invalidateQueries(['stories', projectId]); }); // Task events (similar) const unsubTaskCreated = handlers.subscribe('task:created', (event) => { queryClient.invalidateQueries(['tasks', projectId]); }); const unsubTaskStatusChanged = handlers.subscribe('task:statusChanged', (event) => { // Animate card movement between columns queryClient.setQueryData(['tasks', projectId], (old: Task[]) => { return old.map(t => t.id === event.taskId ? { ...t, status: event.newStatus } : t); }); }); // Cleanup subscriptions return () => { unsubEpicCreated(); unsubEpicUpdated(); unsubEpicDeleted(); unsubStoryCreated(); unsubTaskCreated(); unsubTaskStatusChanged(); }; }, [isConnected, service, projectId, queryClient]); // ... rest of component }; ``` ### Add Card Animation (1h) ```typescript // Use framer-motion for smooth animations import { motion } from 'framer-motion'; export const KanbanCard: React.FC<{ item: any }> = ({ item }) => { return ( {/* Card content */} ); }; ``` ## Acceptance Criteria - [ ] Kanban updates automatically on SignalR events - [ ] All 13 event types handled - [ ] Card animations smooth (60 FPS) - [ ] No duplicate cards after updates - [ ] Optimistic updates working ## Deliverables 1. SignalR integration in KanbanBoard.tsx 2. Card animations with framer-motion 3. Integration tests (8+ scenarios) **Status**: Not Started | **Created**: 2025-11-04