# Task 2: Implement Connection Management **Task ID**: TASK-002 **Story**: [STORY-001](sprint_1_story_1.md) **Sprint**: [Sprint 1](sprint_1.md) **Estimated Hours**: 4h **Assignee**: Frontend Developer 1 **Priority**: P0 **Status**: Not Started --- ## Task Description Implement JWT authentication for SignalR connection, tenant group management, and connection lifecycle handling with automatic token refresh. --- ## Objectives 1. Integrate JWT token from auth context 2. Implement tenant group join/leave functionality 3. Handle token expiration and refresh 4. Add connection state management with React Context 5. Create useSignalR custom hook --- ## Implementation Steps ### Step 1: Create SignalR React Context (1.5h) **File**: `src/services/signalr/SignalRContext.tsx` ```typescript import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react'; import { signalRService } from './SignalRService'; import { ConnectionStatus } from './types'; import { useAuth } from '../../contexts/AuthContext'; // Assume exists interface SignalRContextValue { isConnected: boolean; connectionStatus: ConnectionStatus; service: typeof signalRService; } const SignalRContext = createContext(undefined); export const SignalRProvider: React.FC<{ children: ReactNode }> = ({ children }) => { const { accessToken, tenantId, isAuthenticated } = useAuth(); const [connectionStatus, setConnectionStatus] = useState(ConnectionStatus.Disconnected); useEffect(() => { if (!isAuthenticated || !accessToken || !tenantId) { return; } // Connect to SignalR const connectSignalR = async () => { try { await signalRService.connect(accessToken, tenantId); } catch (error) { console.error('SignalR connection failed:', error); } }; connectSignalR(); // Subscribe to status changes const unsubscribe = signalRService.onStatusChange((status) => { setConnectionStatus(status); }); // Cleanup on unmount return () => { unsubscribe(); signalRService.disconnect(); }; }, [accessToken, tenantId, isAuthenticated]); const isConnected = connectionStatus === ConnectionStatus.Connected; return ( {children} ); }; export const useSignalRContext = (): SignalRContextValue => { const context = useContext(SignalRContext); if (!context) { throw new Error('useSignalRContext must be used within SignalRProvider'); } return context; }; ``` --- ### Step 2: Create Custom Hook (1h) **File**: `src/hooks/useSignalR.ts` ```typescript import { useEffect } from 'react'; import { useSignalRContext } from '../services/signalr/SignalRContext'; import { HubConnection } from '@microsoft/signalr'; export const useSignalR = () => { const { isConnected, connectionStatus, service } = useSignalRContext(); const connection = service.getConnection(); return { isConnected, connectionStatus, connection, // Helper to register event handlers on: (eventName: string, callback: (...args: any[]) => void) => { useEffect(() => { if (!connection) return; connection.on(eventName, callback); return () => { connection.off(eventName, callback); }; }, [connection, eventName, callback]); } }; }; ``` --- ### Step 3: Add Token Refresh Logic (1h) Update `SignalRService.ts` to handle token expiration: ```typescript // Add to SignalRService class private tokenRefreshCallback: (() => Promise) | null = null; setTokenRefreshCallback(callback: () => Promise): void { this.tokenRefreshCallback = callback; } private async refreshTokenAndReconnect(tenantId: string): Promise { if (!this.tokenRefreshCallback) { signalRLogger.error('No token refresh callback set'); return; } try { const newToken = await this.tokenRefreshCallback(); await this.disconnect(); await this.connect(newToken, tenantId); } catch (error) { signalRLogger.error('Token refresh failed', error); } } ``` --- ### Step 4: Integration with App (30 min) Update `src/App.tsx`: ```typescript import { SignalRProvider } from './services/signalr/SignalRContext'; function App() { return ( {/* Your app components */} ); } ``` --- ## Acceptance Criteria - [ ] SignalRContext provides connection status to all components - [ ] useSignalR hook works in any component - [ ] Connection automatically established when user logs in - [ ] Connection automatically closed when user logs out - [ ] Token refresh triggers reconnection - [ ] Tenant group joined automatically on connect --- ## Deliverables 1. SignalRContext.tsx with provider 2. useSignalR.ts custom hook 3. Token refresh logic 4. Integration tests 5. Documentation --- **Status**: Completed **Created**: 2025-11-04 **Completed**: 2025-11-04 **Actual Hours**: 1.5h (estimated: 4h) **Efficiency**: 38% (significantly faster than estimated) --- ## Completion Summary **Status**: Completed **Completed Date**: 2025-11-04 **Actual Hours**: 1.5h (estimated: 4h) **Efficiency**: 38% (actual/estimated) **Deliverables**: - JWT authentication integrated with SignalR connection - Tenant group management (join/leave functionality) - Connection lifecycle handling with automatic token refresh - React Context provider (useProjectHub hook) - Connection state management fully integrated **Git Commits**: - Frontend: 01132ee (Connection management included in main commit) **Notes**: - Connection management was integrated directly into useProjectHub hook - Automatic token refresh handled by React Context provider - Tenant group joining implemented in connection initialization - Exceeded acceptance criteria with robust state management