# 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<SignalRContextValue | undefined>(undefined);

export const SignalRProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const { accessToken, tenantId, isAuthenticated } = useAuth();
  const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>(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 (
    <SignalRContext.Provider value={{ isConnected, connectionStatus, service: signalRService }}>
      {children}
    </SignalRContext.Provider>
  );
};

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<string>) | null = null;

setTokenRefreshCallback(callback: () => Promise<string>): void {
  this.tokenRefreshCallback = callback;
}

private async refreshTokenAndReconnect(tenantId: string): Promise<void> {
  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 (
    <AuthProvider>
      <SignalRProvider>
        {/* Your app components */}
      </SignalRProvider>
    </AuthProvider>
  );
}
```

---

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