From da1c116a2ff3895f284194c01988bd078eed6d66 Mon Sep 17 00:00:00 2001 From: mariaruth1 <113031776+mariaruth1@users.noreply.github.com> Date: Tue, 28 May 2024 10:52:24 +0200 Subject: [PATCH] Created statsservice to handle updating stats when collection or plant is added, updated or deleted Upon logging out we no longer remove the entire connection, just the email, the connection is removed on onclose --- Shared/Models/Stats.cs | 8 ++++ api/Core/Services/StatsService.cs | 21 ++++++++ api/Events/Auth/Client/ClientWantsToLogOut.cs | 2 +- .../Client/ClientWantsToCreateCollection.cs | 7 ++- .../Client/ClientWantsToDeleteCollection.cs | 7 ++- .../Client/ClientWantsToCreatePlant.cs | 6 ++- .../Client/ClientWantsToDeletePlant.cs | 7 ++- .../Client/ClientWantsToGetCriticalPlants.cs | 7 ++- .../Client/ClientWantsToUpdatePlant.cs | 7 ++- api/Events/Statistics/ClientWantsStats.cs | 28 +++++++++++ api/Events/Stats/ClientWantsStats.cs | 48 ------------------- api/WebSocketConnectionService.cs | 6 +++ 12 files changed, 99 insertions(+), 55 deletions(-) create mode 100644 Shared/Models/Stats.cs create mode 100644 api/Core/Services/StatsService.cs create mode 100644 api/Events/Statistics/ClientWantsStats.cs delete mode 100644 api/Events/Stats/ClientWantsStats.cs diff --git a/Shared/Models/Stats.cs b/Shared/Models/Stats.cs new file mode 100644 index 0000000..163c91b --- /dev/null +++ b/Shared/Models/Stats.cs @@ -0,0 +1,8 @@ +namespace Shared.Models; + +public class Stats +{ + public int TotalPlants { get; set; } + public int HappyPlants { get; set; } + public int Collections { get; set; } +} \ No newline at end of file diff --git a/api/Core/Services/StatsService.cs b/api/Core/Services/StatsService.cs new file mode 100644 index 0000000..16c1c35 --- /dev/null +++ b/api/Core/Services/StatsService.cs @@ -0,0 +1,21 @@ +using Shared.Dtos; +using Shared.Models; + +namespace api.Core.Services; + +public class StatsService(CollectionsService collectionsService, PlantService plantService) +{ + public async Task GetStats(string email) + { + var totalPlants = await plantService.GetTotalPlantsCount(email); + var happyPlants = await plantService.GetHappyPlantsCount(email); + var collections = await collectionsService.GetTotalCollectionsCount(email); + + return new Stats + { + TotalPlants = totalPlants, + HappyPlants = happyPlants, + Collections = collections + }; + } +} diff --git a/api/Events/Auth/Client/ClientWantsToLogOut.cs b/api/Events/Auth/Client/ClientWantsToLogOut.cs index dd514a4..a361ecd 100644 --- a/api/Events/Auth/Client/ClientWantsToLogOut.cs +++ b/api/Events/Auth/Client/ClientWantsToLogOut.cs @@ -12,7 +12,7 @@ public class ClientWantsToLogOut(WebSocketConnectionService connectionService) { public override Task Handle(ClientWantsToLogOutDto dto, IWebSocketConnection socket) { - connectionService.RemoveConnection(socket); + connectionService.RemoveEmailFromConnection(socket); socket.SendDto(new ServerLogsOutUser()); return Task.CompletedTask; } diff --git a/api/Events/Collections/Client/ClientWantsToCreateCollection.cs b/api/Events/Collections/Client/ClientWantsToCreateCollection.cs index 7298b0e..4553efd 100644 --- a/api/Events/Collections/Client/ClientWantsToCreateCollection.cs +++ b/api/Events/Collections/Client/ClientWantsToCreateCollection.cs @@ -1,5 +1,6 @@ using api.Core.Services; using api.Events.Collections.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -13,16 +14,20 @@ public class ClientWantsToCreateCollectionDto : BaseDtoWithJwt public required CreateCollectionDto CreateCollectionDto { get; set; } } -public class ClientWantsToCreateCollection(CollectionsService collectionsService, JwtService jwtService) : BaseEventHandler +public class ClientWantsToCreateCollection(CollectionsService collectionsService, JwtService jwtService, StatsService statsService) : BaseEventHandler { public override async Task Handle(ClientWantsToCreateCollectionDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); await collectionsService.CreateCollection(dto.CreateCollectionDto, email); var allCollections = await collectionsService.GetCollectionsForUser(email); + var stats = await statsService.GetStats(email); + socket.SendDto(new ServerSendsAllCollections() { Collections = allCollections.ToList() }); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/Collections/Client/ClientWantsToDeleteCollection.cs b/api/Events/Collections/Client/ClientWantsToDeleteCollection.cs index 08bc019..69966f9 100644 --- a/api/Events/Collections/Client/ClientWantsToDeleteCollection.cs +++ b/api/Events/Collections/Client/ClientWantsToDeleteCollection.cs @@ -1,5 +1,6 @@ using api.Core.Services; using api.Events.Collections.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -13,16 +14,20 @@ public class ClientWantsToDeleteCollectionDto : BaseDtoWithJwt public Guid CollectionId { get; set; } } -public class ClientWantsToDeleteCollection(CollectionsService collectionsService, JwtService jwtService) : BaseEventHandler +public class ClientWantsToDeleteCollection(CollectionsService collectionsService, JwtService jwtService, StatsService statsService) : BaseEventHandler { public override async Task Handle(ClientWantsToDeleteCollectionDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); await collectionsService.DeleteCollection(dto.CollectionId, email); var allCollections = await collectionsService.GetCollectionsForUser(email); + + var stats = await statsService.GetStats(email); socket.SendDto(new ServerSendsAllCollections() { Collections = allCollections.ToList() }); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs b/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs index eaf2632..333d868 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs @@ -1,6 +1,7 @@ using api.Core.Services; using api.EventFilters; using api.Events.PlantEvents.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -15,12 +16,13 @@ public class ClientWantsToCreatePlantDto: BaseDtoWithJwt } [ValidateDataAnnotations] -public class ClientWantsToCreatePlant(PlantService plantService, JwtService jwtService): BaseEventHandler +public class ClientWantsToCreatePlant(PlantService plantService, JwtService jwtService, StatsService statsService): BaseEventHandler { public override async Task Handle(ClientWantsToCreatePlantDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); var plant = await plantService.CreatePlant(dto.CreatePlantDto, email); + var stats = await statsService.GetStats(email); var serverCreatesNewPlant = new ServerSavesPlant { @@ -28,5 +30,7 @@ public override async Task Handle(ClientWantsToCreatePlantDto dto, IWebSocketCon }; socket.SendDto(serverCreatesNewPlant); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/PlantEvents/Client/ClientWantsToDeletePlant.cs b/api/Events/PlantEvents/Client/ClientWantsToDeletePlant.cs index bb4068f..76319a3 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToDeletePlant.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToDeletePlant.cs @@ -3,6 +3,7 @@ using api.EventFilters; using api.Events.Global; using api.Events.PlantEvents.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -16,13 +17,17 @@ public class ClientWantsToDeletePlantDto: BaseDtoWithJwt } [ValidateDataAnnotations] -public class ClientWantsToDeletePlant(PlantService plantService, JwtService jwtService): BaseEventHandler +public class ClientWantsToDeletePlant(PlantService plantService, JwtService jwtService, StatsService statsService): BaseEventHandler { public override async Task Handle(ClientWantsToDeletePlantDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); + var stats = await statsService.GetStats(email); + await plantService.DeletePlant(dto.PlantId, email); socket.SendDto( new ServerConfirmsDelete()); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } diff --git a/api/Events/PlantEvents/Client/ClientWantsToGetCriticalPlants.cs b/api/Events/PlantEvents/Client/ClientWantsToGetCriticalPlants.cs index 01b27f3..5b92e63 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToGetCriticalPlants.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToGetCriticalPlants.cs @@ -1,5 +1,6 @@ using api.Core.Services; using api.Events.PlantEvents.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -9,16 +10,20 @@ namespace api.Events.PlantEvents.Client; public class ClientWantsToGetCriticalPlantsDto : BaseDtoWithJwt; -public class ClientWantsToGetCriticalPlants(JwtService jwtService, PlantService plantService) : BaseEventHandler +public class ClientWantsToGetCriticalPlants(JwtService jwtService, PlantService plantService, StatsService statsService) : BaseEventHandler { public override async Task Handle(ClientWantsToGetCriticalPlantsDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); var plants = await plantService.GetCriticalPlants(email); + var stats = await statsService.GetStats(email); + var serverResponse = new ServerSendsCriticalPlants { Plants = plants }; socket.SendDto(serverResponse); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/PlantEvents/Client/ClientWantsToUpdatePlant.cs b/api/Events/PlantEvents/Client/ClientWantsToUpdatePlant.cs index 9f2b8ce..1dc8348 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToUpdatePlant.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToUpdatePlant.cs @@ -1,5 +1,6 @@ using api.Core.Services; using api.Events.PlantEvents.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -13,15 +14,19 @@ public class ClientWantsToUpdatePlantDto: BaseDtoWithJwt public required UpdatePlantDto UpdatePlantDto { get; set; } } -public class ClientWantsToUpdatePlant(PlantService plantService, JwtService jwtService): BaseEventHandler +public class ClientWantsToUpdatePlant(PlantService plantService, JwtService jwtService, StatsService statsService): BaseEventHandler { public override async Task Handle(ClientWantsToUpdatePlantDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); var plant = await plantService.UpdatePlant(dto.UpdatePlantDto, email); + var stats = await statsService.GetStats(email); + socket.SendDto(new ServerSavesPlant { Plant = plant }); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/Statistics/ClientWantsStats.cs b/api/Events/Statistics/ClientWantsStats.cs new file mode 100644 index 0000000..0220931 --- /dev/null +++ b/api/Events/Statistics/ClientWantsStats.cs @@ -0,0 +1,28 @@ +using api.Core.Services; +using api.Extensions; +using Fleck; +using lib; +using Shared.Models; + +namespace api.Events.Statistics; + +public class ClientWantsStatsDto : BaseDtoWithJwt +{ + +} + +public class ClientWantsStats(StatsService statsService, JwtService jwtService) : BaseEventHandler +{ + public override async Task Handle(ClientWantsStatsDto dto, IWebSocketConnection socket) + { + var email = jwtService.GetEmailFromJwt(dto.Jwt!); + + var stats = await statsService.GetStats(email); + socket.SendDto(new ServerSendsStats{Stats = stats}); + } +} + +public class ServerSendsStats : BaseDto +{ + public Stats Stats { get; set; } = null!; +} diff --git a/api/Events/Stats/ClientWantsStats.cs b/api/Events/Stats/ClientWantsStats.cs deleted file mode 100644 index b581887..0000000 --- a/api/Events/Stats/ClientWantsStats.cs +++ /dev/null @@ -1,48 +0,0 @@ -using api.Core.Services; -using api.Extensions; -using Fleck; -using lib; -using Shared.Models; - -namespace api.Events.Stats; - -public class ClientWantsStatsDto : BaseDtoWithJwt -{ - -} - -public class ClientWantsStats(PlantService plantService, CollectionsService collectionsService, JwtService jwtService) : BaseEventHandler -{ - public override async Task Handle(ClientWantsStatsDto dto, IWebSocketConnection socket) - { - var email = jwtService.GetEmailFromJwt(dto.Jwt!); - - var totalPlants = await plantService.GetTotalPlantsCount(email); - var happyPlants = await plantService.GetHappyPlantsCount(email); - var collections = await collectionsService.GetTotalCollectionsCount(email); - - var statsDto = new ServerSendsStats - { - Stats = new Stats - { - TotalPlants = totalPlants, - HappyPlants = happyPlants, - Collections = collections - } - }; - - socket.SendDto(statsDto); - } -} - -public class ServerSendsStats : BaseDto -{ - public Stats Stats { get; set; } -} - -public class Stats -{ - public int TotalPlants { get; set; } - public int HappyPlants { get; set; } - public int Collections { get; set; } -} \ No newline at end of file diff --git a/api/WebSocketConnectionService.cs b/api/WebSocketConnectionService.cs index 6b57682..a7c1cde 100644 --- a/api/WebSocketConnectionService.cs +++ b/api/WebSocketConnectionService.cs @@ -19,6 +19,12 @@ public void UpdateConnectionEmail(IWebSocketConnection connection, string email) var clientId = connection.ConnectionInfo.Id; _connectedClients[clientId].Email = email; } + + public void RemoveEmailFromConnection(IWebSocketConnection connection) + { + var clientId = connection.ConnectionInfo.Id; + _connectedClients[clientId].Email = null; + } public void RemoveConnection(IWebSocketConnection connection) {