using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; namespace OTSSignsOrchestrator.Server.Hubs; /// /// Server→client push-only hub for real-time fleet notifications. /// Desktop clients never send messages via SignalR — they use REST for commands. /// [Authorize] public class FleetHub : Hub { private readonly ILogger _logger; public FleetHub(ILogger logger) { _logger = logger; } public override Task OnConnectedAsync() { var name = Context.User?.FindFirst(ClaimTypes.Name)?.Value ?? "unknown"; _logger.LogInformation("FleetHub: operator {Name} connected (connId={ConnectionId})", name, Context.ConnectionId); return base.OnConnectedAsync(); } public override Task OnDisconnectedAsync(Exception? exception) { var name = Context.User?.FindFirst(ClaimTypes.Name)?.Value ?? "unknown"; _logger.LogInformation("FleetHub: operator {Name} disconnected (connId={ConnectionId})", name, Context.ConnectionId); return base.OnDisconnectedAsync(exception); } } /// /// Strongly-typed client interface for FleetHub push messages. /// Inject IHubContext<FleetHub, IFleetClient> to call these from services. /// public interface IFleetClient { Task SendJobCreated(string jobId, string abbrev, string jobType); Task SendJobProgressUpdate(string jobId, string stepName, int pct, string logLine); Task SendJobCompleted(string jobId, bool success, string summary); Task SendInstanceStatusChanged(string customerId, string status); Task SendAlertRaised(string severity, string message); }