using Microsoft.AspNetCore.SignalR; using PlotLine.Hubs; using PlotLine.Models; namespace PlotLine.Services; public interface IStoryIntelligenceProgressNotifier { Task PublishAsync(StoryIntelligenceRunProgressEvent progress); Task PublishCharacterEnrichmentAsync(CharacterEnrichmentProgressEvent progress); Task PublishGlobalAsync(int userId); } public sealed class StoryIntelligenceProgressNotifier( IHubContext hub, IStoryIntelligenceGlobalProgressService globalProgress) : IStoryIntelligenceProgressNotifier { public async Task PublishAsync(StoryIntelligenceRunProgressEvent progress) { var userGroup = StoryIntelligenceHub.UserGroup(progress.UserID); await hub.Clients.Group(userGroup) .SendAsync("StoryIntelligenceRunProgressChanged", progress); await PublishGlobalAsync(progress.UserID); } public async Task PublishCharacterEnrichmentAsync(CharacterEnrichmentProgressEvent progress) { var userGroup = StoryIntelligenceHub.UserGroup(progress.UserID); await hub.Clients.Group(userGroup) .SendAsync("CharacterEnrichmentProgressChanged", progress); } public async Task PublishGlobalAsync(int userId) { var userGroup = StoryIntelligenceHub.UserGroup(userId); var aggregate = await globalProgress.GetForUserAsync(userId); await hub.Clients.Group(userGroup) .SendAsync("StoryIntelligenceGlobalProgressChanged", aggregate); } }