# 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 (
    <motion.div
      layout
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -20 }}
      transition={{ duration: 0.3 }}
      className="kanban-card"
    >
      {/* Card content */}
    </motion.div>
  );
};
```

## 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
