Files
ColaFlow/colaflow-api/SIGNALR-IMPLEMENTATION.md
Yaojia Wang 5a1ad2eb97 feat(backend): Implement SignalR real-time communication infrastructure
Add complete SignalR infrastructure for real-time project collaboration and notifications with multi-tenant isolation and JWT authentication.

Changes:
- Created BaseHub with multi-tenant isolation and JWT authentication helpers
- Created ProjectHub for real-time project collaboration (join/leave, typing indicators)
- Created NotificationHub for user-level notifications
- Implemented IRealtimeNotificationService for application layer integration
- Configured SignalR in Program.cs with CORS and JWT query string support
- Added SignalRTestController for connection testing
- Documented hub endpoints, client events, and integration examples

Features:
- Multi-tenant isolation via automatic tenant group membership
- JWT authentication (Bearer header + query string for WebSocket)
- Hub endpoints: /hubs/project, /hubs/notification
- Project-level events: IssueCreated, IssueUpdated, IssueStatusChanged, etc.
- User-level notifications with tenant-wide broadcasting
- Test endpoints for validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 09:04:13 +01:00

10 KiB

SignalR Real-time Communication Implementation

Overview

This document describes the SignalR real-time communication infrastructure implemented for ColaFlow. The implementation provides real-time updates for project collaboration, issue tracking, and user notifications with multi-tenant isolation and JWT authentication.

Implementation Date

2025-11-04

Components Implemented

1. Hub Infrastructure

BaseHub (src/ColaFlow.API/Hubs/BaseHub.cs)

Base class for all SignalR hubs with:

  • JWT Authentication: All hubs require authentication via [Authorize] attribute
  • Multi-tenant Isolation: Automatically adds users to tenant-specific groups on connection
  • User/Tenant Extraction: Helper methods to extract user ID and tenant ID from JWT claims
  • Connection Lifecycle: Logging for connect/disconnect events

Key Features:

  • GetCurrentUserId(): Extracts user ID from JWT token (sub or user_id claim)
  • GetCurrentTenantId(): Extracts tenant ID from JWT token (tenant_id claim)
  • GetTenantGroupName(Guid tenantId): Returns standardized tenant group name
  • Automatic group membership on connection
  • Error handling with connection abort on authentication failures

ProjectHub (src/ColaFlow.API/Hubs/ProjectHub.cs)

Hub for project-level real-time collaboration:

Methods:

  • JoinProject(Guid projectId): Join a project room to receive updates
  • LeaveProject(Guid projectId): Leave a project room
  • SendTypingIndicator(Guid projectId, Guid issueId, bool isTyping): Send typing indicators

Client Events:

  • UserJoinedProject: Notifies when a user joins a project
  • UserLeftProject: Notifies when a user leaves a project
  • TypingIndicator: Real-time typing indicators for issue editing
  • ProjectUpdated: General project updates
  • IssueCreated: New issue created
  • IssueUpdated: Issue updated
  • IssueDeleted: Issue deleted
  • IssueStatusChanged: Issue status changed

NotificationHub (src/ColaFlow.API/Hubs/NotificationHub.cs)

Hub for user-level notifications:

Methods:

  • MarkAsRead(Guid notificationId): Mark a notification as read

Client Events:

  • Notification: General notifications
  • NotificationRead: Confirmation of read status

2. Realtime Notification Service

IRealtimeNotificationService (src/ColaFlow.API/Services/IRealtimeNotificationService.cs)

Service interface for sending real-time notifications from application layer.

Project-level Methods:

  • NotifyProjectUpdate(Guid tenantId, Guid projectId, object data)
  • NotifyIssueCreated(Guid tenantId, Guid projectId, object issue)
  • NotifyIssueUpdated(Guid tenantId, Guid projectId, object issue)
  • NotifyIssueDeleted(Guid tenantId, Guid projectId, Guid issueId)
  • NotifyIssueStatusChanged(Guid tenantId, Guid projectId, Guid issueId, string oldStatus, string newStatus)

User-level Methods:

  • NotifyUser(Guid userId, string message, string type = "info")
  • NotifyUsersInTenant(Guid tenantId, string message, string type = "info")

RealtimeNotificationService (src/ColaFlow.API/Services/RealtimeNotificationService.cs)

Implementation of the notification service using IHubContext<T>.

3. Configuration

Program.cs Updates

SignalR Configuration:

builder.Services.AddSignalR(options =>
{
    options.EnableDetailedErrors = builder.Environment.IsDevelopment();
    options.ClientTimeoutInterval = TimeSpan.FromSeconds(60);
    options.HandshakeTimeout = TimeSpan.FromSeconds(15);
    options.KeepAliveInterval = TimeSpan.FromSeconds(15);
});

CORS Configuration (SignalR-compatible):

builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowFrontend", policy =>
    {
        policy.WithOrigins("http://localhost:3000", "https://localhost:3000")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials(); // Required for SignalR
    });
});

JWT Authentication for SignalR (Query String Support):

options.Events = new JwtBearerEvents
{
    OnMessageReceived = context =>
    {
        var accessToken = context.Request.Query["access_token"];
        var path = context.HttpContext.Request.Path;
        if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hubs"))
        {
            context.Token = accessToken;
        }
        return Task.CompletedTask;
    }
};

Hub Endpoints:

app.MapHub<ProjectHub>("/hubs/project");
app.MapHub<NotificationHub>("/hubs/notification");

Service Registration:

builder.Services.AddScoped<IRealtimeNotificationService, RealtimeNotificationService>();

4. Test Controller

SignalRTestController (src/ColaFlow.API/Controllers/SignalRTestController.cs)

Controller for testing SignalR functionality:

Endpoints:

  • POST /api/SignalRTest/test-user-notification: Send notification to current user
  • POST /api/SignalRTest/test-tenant-notification: Send notification to entire tenant
  • POST /api/SignalRTest/test-project-update: Send project update notification
  • POST /api/SignalRTest/test-issue-status-change: Send issue status change notification
  • GET /api/SignalRTest/connection-info: Get connection information for debugging

SignalR Hub Endpoints

Hub Endpoint Description
ProjectHub /hubs/project Project-level real-time collaboration
NotificationHub /hubs/notification User-level notifications

Authentication

SignalR hubs use JWT authentication with two methods:

  1. Authorization Header: Standard Bearer {token} in HTTP headers
  2. Query String: ?access_token={token} for WebSocket upgrade requests

All hubs are protected with [Authorize] attribute and require valid JWT tokens.

Multi-Tenant Isolation

Users are automatically added to their tenant group (tenant-{tenantId}) on connection. This ensures:

  • Notifications are only sent within tenant boundaries
  • Cross-tenant data leakage is prevented
  • Group-based broadcasting is efficient

Client Connection Example

JavaScript/TypeScript (SignalR Client)

import * as signalR from "@microsoft/signalr";

const connection = new signalR.HubConnectionBuilder()
  .withUrl("https://localhost:5001/hubs/project", {
    accessTokenFactory: () => getAccessToken() // Your JWT token
  })
  .withAutomaticReconnect()
  .build();

// Listen for events
connection.on("IssueCreated", (issue) => {
  console.log("New issue:", issue);
});

connection.on("IssueStatusChanged", (data) => {
  console.log("Issue status changed:", data);
});

// Start connection
await connection.start();

// Join project
await connection.invoke("JoinProject", projectId);

// Send typing indicator
await connection.invoke("SendTypingIndicator", projectId, issueId, true);

Integration with Domain Events

To send SignalR notifications from application layer:

public class IssueCreatedEventHandler : INotificationHandler<IssueCreatedEvent>
{
    private readonly IRealtimeNotificationService _realtimeNotification;

    public async Task Handle(IssueCreatedEvent notification, CancellationToken cancellationToken)
    {
        await _realtimeNotification.NotifyIssueCreated(
            notification.TenantId,
            notification.ProjectId,
            new
            {
                Id = notification.IssueId,
                Title = notification.Title,
                Status = notification.Status
            }
        );
    }
}

Testing

Test Endpoints

  1. Get Connection Info:

    curl -X GET https://localhost:5001/api/SignalRTest/connection-info \
      -H "Authorization: Bearer {your-jwt-token}"
    
  2. Test User Notification:

    curl -X POST https://localhost:5001/api/SignalRTest/test-user-notification \
      -H "Authorization: Bearer {your-jwt-token}" \
      -H "Content-Type: application/json" \
      -d "\"Test notification message\""
    
  3. Test Tenant Notification:

    curl -X POST https://localhost:5001/api/SignalRTest/test-tenant-notification \
      -H "Authorization: Bearer {your-jwt-token}" \
      -H "Content-Type: application/json" \
      -d "\"Test tenant message\""
    
  4. Test Project Update:

    curl -X POST https://localhost:5001/api/SignalRTest/test-project-update \
      -H "Authorization: Bearer {your-jwt-token}" \
      -H "Content-Type: application/json" \
      -d '{"projectId":"00000000-0000-0000-0000-000000000000","message":"Test update"}'
    

Build Status

Build successful with no errors or warnings

cd colaflow-api
dotnet build src/ColaFlow.API/ColaFlow.API.csproj

Success Criteria Checklist

  • SignalR infrastructure added (built-in .NET 9 SignalR)
  • Created BaseHub, ProjectHub, NotificationHub
  • Configured SignalR in Program.cs with CORS and JWT
  • Implemented IRealtimeNotificationService
  • Hub supports multi-tenant isolation (automatic tenant group membership)
  • Hub supports JWT authentication (Bearer + query string)
  • Created test controller (SignalRTestController)
  • Compilation successful with no errors

Files Created/Modified

Created:

  • src/ColaFlow.API/Hubs/BaseHub.cs
  • src/ColaFlow.API/Hubs/ProjectHub.cs
  • src/ColaFlow.API/Hubs/NotificationHub.cs
  • src/ColaFlow.API/Services/IRealtimeNotificationService.cs
  • src/ColaFlow.API/Services/RealtimeNotificationService.cs
  • src/ColaFlow.API/Controllers/SignalRTestController.cs

Modified:

  • src/ColaFlow.API/Program.cs (SignalR configuration, CORS, JWT, hub endpoints)

Next Steps

  1. Frontend Integration: Implement SignalR client in Next.js frontend
  2. Domain Event Integration: Wire up notification service to domain events
  3. Permission Validation: Add authorization checks in ProjectHub.JoinProject()
  4. User Connection Mapping: Implement user-to-connection tracking for targeted notifications
  5. Scalability: Consider Redis backplane for multi-server deployments
  6. Monitoring: Add SignalR performance metrics and connection monitoring

Notes

  • SignalR is built-in to .NET 9.0 ASP.NET Core, no separate NuGet package required
  • CORS policy updated to include AllowCredentials() for SignalR compatibility
  • JWT authentication supports both HTTP Authorization header and query string for WebSocket upgrade
  • All hubs automatically enforce tenant isolation via BaseHub
  • Notification service can be injected into any application service or event handler