From 0c8657713b28fe1dfb33e8bbd304ff0b19ef3c55 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 19 Jan 2026 00:34:57 -0500 Subject: [PATCH] refactor(core): reorganize DTOs into Models and ViewModels folders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move DTOs from ApiContracts to appropriate locations: - SignalR DTOs → ViewModels (renamed Dto→ViewModel suffix) - Pipeline DTOs → Models/Pipelines - UserInfoDto → Models/Auth - DataUpdateDto → Models/Infrastructure --- .../Controllers/AuthController.cs | 1 - .../Controllers/PipelineController.cs | 2 +- .../Controllers/RefreshStatusController.cs | 71 +++++++++++++++++++ NEW/src/JdeScoping.Api/Hubs/StatusHub.cs | 10 +-- .../Services/SearchNotificationService.cs | 6 +- .../Auth/AuthStateProvider.cs | 2 +- .../Auth/IUserStorageService.cs | 2 +- .../Auth/UserStorageService.cs | 2 +- .../Admin/PipelineScheduleSection.razor | 2 +- .../Pages/Admin/PipelineViewer.razor | 2 +- .../Pages/RefreshStatus.razor | 32 ++++----- .../JdeScoping.Client/Pages/SearchEdit.razor | 2 +- .../JdeScoping.Client/Pages/SearchQueue.razor | 4 +- .../JdeScoping.Client/Pages/Searches.razor | 2 +- .../Services/AuthApiClient.cs | 1 - .../Services/HubConnectionService.cs | 14 ++-- .../Services/IHubConnectionService.cs | 8 +-- .../Services/IRefreshStatusService.cs | 4 +- .../Services/PipelineApiClient.cs | 2 +- .../Services/RefreshStatusService.cs | 6 +- NEW/src/JdeScoping.Client/_Imports.razor | 6 +- .../JdeScoping.Core/ApiContracts/ApiRoutes.cs | 13 ++++ .../ApiContracts/IAuthApiClient.cs | 1 - .../ApiContracts/IPipelineApiClient.cs | 2 +- .../Models/Auth/LoginResultModel.cs | 2 - .../Auth/UserInfoDto.cs | 4 +- .../Models/Infrastructure/DataUpdateDto.cs} | 7 +- .../Pipelines/PipelineConfigDto.cs | 2 +- .../Pipelines/PipelineExecutionDto.cs | 4 +- .../Pipelines/PipelineListResponse.cs | 2 +- .../Pipelines/PipelineStatusDto.cs | 4 +- .../SearchUpdateViewModel.cs} | 12 ++-- .../StatusUpdateViewModel.cs} | 12 ++-- .../Controllers/AuthControllerTests.cs | 1 - .../Hubs/StatusHubTests.cs | 6 +- .../Services/AuthApiClientTests.cs | 1 - 36 files changed, 166 insertions(+), 88 deletions(-) create mode 100644 NEW/src/JdeScoping.Api/Controllers/RefreshStatusController.cs rename NEW/src/JdeScoping.Core/{ApiContracts => Models}/Auth/UserInfoDto.cs (91%) rename NEW/src/{JdeScoping.Client/Models/DataUpdateViewModel.cs => JdeScoping.Core/Models/Infrastructure/DataUpdateDto.cs} (75%) rename NEW/src/JdeScoping.Core/{ApiContracts => Models}/Pipelines/PipelineConfigDto.cs (92%) rename NEW/src/JdeScoping.Core/{ApiContracts => Models}/Pipelines/PipelineExecutionDto.cs (77%) rename NEW/src/JdeScoping.Core/{ApiContracts => Models}/Pipelines/PipelineListResponse.cs (73%) rename NEW/src/JdeScoping.Core/{ApiContracts => Models}/Pipelines/PipelineStatusDto.cs (80%) rename NEW/src/JdeScoping.Core/{ApiContracts/SignalR/SearchUpdateDto.cs => ViewModels/SearchUpdateViewModel.cs} (76%) rename NEW/src/JdeScoping.Core/{ApiContracts/SignalR/StatusUpdateDto.cs => ViewModels/StatusUpdateViewModel.cs} (55%) diff --git a/NEW/src/JdeScoping.Api/Controllers/AuthController.cs b/NEW/src/JdeScoping.Api/Controllers/AuthController.cs index c8bd356..cc94c4a 100644 --- a/NEW/src/JdeScoping.Api/Controllers/AuthController.cs +++ b/NEW/src/JdeScoping.Api/Controllers/AuthController.cs @@ -2,7 +2,6 @@ using System.Security.Claims; using System.Text.Json; using JdeScoping.Api.Extensions; using JdeScoping.Core.ApiContracts; -using JdeScoping.Core.ApiContracts.Auth; using JdeScoping.Core.Interfaces; using JdeScoping.Core.Models; using JdeScoping.Core.Models.Auth; diff --git a/NEW/src/JdeScoping.Api/Controllers/PipelineController.cs b/NEW/src/JdeScoping.Api/Controllers/PipelineController.cs index c102ab5..92b0cb2 100644 --- a/NEW/src/JdeScoping.Api/Controllers/PipelineController.cs +++ b/NEW/src/JdeScoping.Api/Controllers/PipelineController.cs @@ -1,5 +1,5 @@ using JdeScoping.Core.ApiContracts; -using JdeScoping.Core.ApiContracts.Pipelines; +using JdeScoping.Core.Models.Pipelines; using JdeScoping.Core.Models.Enums; using JdeScoping.DataSync.Configuration; using JdeScoping.DataSync.Contracts; diff --git a/NEW/src/JdeScoping.Api/Controllers/RefreshStatusController.cs b/NEW/src/JdeScoping.Api/Controllers/RefreshStatusController.cs new file mode 100644 index 0000000..58b8fbf --- /dev/null +++ b/NEW/src/JdeScoping.Api/Controllers/RefreshStatusController.cs @@ -0,0 +1,71 @@ +using JdeScoping.Core.ApiContracts; +using JdeScoping.Core.Models.Infrastructure; +using JdeScoping.Core.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace JdeScoping.Api.Controllers; + +/// +/// API endpoints for data refresh/cache sync status. +/// +[Route(ApiRoutes.RefreshStatus.Base)] +[ApiController] +[Authorize] +public class RefreshStatusController : ApiControllerBase +{ + private readonly ILotFinderRepository _repository; + + public RefreshStatusController(ILotFinderRepository repository) + { + _repository = repository; + } + + /// + /// Gets aggregated refresh status records within the specified date range. + /// + /// Start date filter. + /// End date filter. + /// Cancellation token. + [HttpGet] + [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] + public async Task>> GetRefreshStatus( + [FromQuery] DateTime minDT, + [FromQuery] DateTime maxDT, + CancellationToken ct) + { + // Get raw data updates from repository + var updates = await _repository.GetLastDataUpdatesAsync(ct); + + // Filter by date range + var filtered = updates + .Where(u => u.StartDt >= minDT && u.StartDt <= maxDT.AddDays(1)) + .ToList(); + + // Group by StartDt (rounded to minute) to aggregate multiple table updates into single rows + var aggregated = filtered + .GroupBy(u => new DateTime(u.StartDt.Year, u.StartDt.Month, u.StartDt.Day, u.StartDt.Hour, u.StartDt.Minute, 0)) + .Select(g => new DataUpdateDto + { + StartDt = g.Key, + EndDt = g.Max(u => u.EndDt), + WasSuccessful = g.All(u => u.WasSuccessful), + BranchRecords = (int)(g.FirstOrDefault(u => u.TableName == "Branch")?.NumberRecords ?? 0), + ProfitCenterRecords = (int)(g.FirstOrDefault(u => u.TableName == "ProfitCenter")?.NumberRecords ?? 0), + WorkCenterRecords = (int)(g.FirstOrDefault(u => u.TableName == "WorkCenter")?.NumberRecords ?? 0), + OrgHierarchyRecords = (int)(g.FirstOrDefault(u => u.TableName == "OrgHierarchy")?.NumberRecords ?? 0), + StatusCodeRecords = (int)(g.FirstOrDefault(u => u.TableName == "StatusCode")?.NumberRecords ?? 0), + UserRecords = (int)(g.FirstOrDefault(u => u.TableName == "JdeUser")?.NumberRecords ?? 0), + ItemRecords = (int)(g.FirstOrDefault(u => u.TableName == "Item")?.NumberRecords ?? 0), + LotRecords = (int)(g.FirstOrDefault(u => u.TableName == "Lot")?.NumberRecords ?? 0), + WorkOrderRecords = (int)(g.FirstOrDefault(u => u.TableName.Contains("WorkOrder_"))?.NumberRecords ?? 0), + WorkOrderStepRecords = (int)(g.FirstOrDefault(u => u.TableName.Contains("WorkOrderStep"))?.NumberRecords ?? 0), + WorkOrderComponentRecords = (int)(g.FirstOrDefault(u => u.TableName.Contains("WorkOrderComponent"))?.NumberRecords ?? 0) + }) + .OrderByDescending(d => d.StartDt) + .ToList(); + + return Ok(aggregated); + } +} diff --git a/NEW/src/JdeScoping.Api/Hubs/StatusHub.cs b/NEW/src/JdeScoping.Api/Hubs/StatusHub.cs index 6d8af25..fcb38fd 100644 --- a/NEW/src/JdeScoping.Api/Hubs/StatusHub.cs +++ b/NEW/src/JdeScoping.Api/Hubs/StatusHub.cs @@ -1,4 +1,4 @@ -using JdeScoping.Core.ApiContracts.SignalR; +using JdeScoping.Core.ViewModels; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; @@ -9,7 +9,7 @@ namespace JdeScoping.Api.Hubs; /// public class StatusHub : Hub { - private static StatusUpdateDto _cachedStatus = new() + private static StatusUpdateViewModel _cachedStatus = new() { Message = "Unknown", Timestamp = DateTime.UtcNow @@ -27,7 +27,7 @@ public class StatusHub : Hub /// Caches the update and broadcasts to all clients. /// /// Status update to broadcast - public async Task SetStatus(StatusUpdateDto statusUpdate) + public async Task SetStatus(StatusUpdateViewModel statusUpdate) { _cachedStatus = statusUpdate; await Clients.All.SendAsync("statusUpdate", statusUpdate); @@ -38,7 +38,7 @@ public class StatusHub : Hub /// Called by clients to get initial cached status on connection. /// /// The most recent status update - public StatusUpdateDto GetCachedStatus() + public StatusUpdateViewModel GetCachedStatus() { return _cachedStatus; } @@ -47,7 +47,7 @@ public class StatusHub : Hub /// Called by controllers/services to broadcast search updates. /// /// Search update to broadcast - public async Task PublishSearchUpdate(SearchUpdateDto searchUpdate) + public async Task PublishSearchUpdate(SearchUpdateViewModel searchUpdate) { await Clients.All.SendAsync("searchUpdate", searchUpdate); _logger.LogDebug("Search update published: ID={Id}, Status={Status}", searchUpdate.Id, searchUpdate.Status); diff --git a/NEW/src/JdeScoping.Api/Services/SearchNotificationService.cs b/NEW/src/JdeScoping.Api/Services/SearchNotificationService.cs index 45e6d52..169ba96 100644 --- a/NEW/src/JdeScoping.Api/Services/SearchNotificationService.cs +++ b/NEW/src/JdeScoping.Api/Services/SearchNotificationService.cs @@ -1,7 +1,7 @@ using JdeScoping.Api.Hubs; -using JdeScoping.Core.ApiContracts.SignalR; using JdeScoping.Core.Interfaces; using JdeScoping.Core.Models.Search; +using JdeScoping.Core.ViewModels; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; @@ -34,7 +34,7 @@ public class SearchNotificationService : ISearchNotificationService { try { - var update = SearchUpdateDto.FromSearch(search); + var update = SearchUpdateViewModel.FromSearch(search); await _hubContext.Clients.All.SendAsync("searchUpdate", update, ct); _logger.LogDebug( "Search update notification sent: Id={SearchId}, Status={Status}", @@ -56,7 +56,7 @@ public class SearchNotificationService : ISearchNotificationService { try { - var update = StatusUpdateDto.Create(status); + var update = StatusUpdateViewModel.Create(status); await _hubContext.Clients.All.SendAsync("statusUpdate", update, ct); _logger.LogDebug("Status notification sent: {Status}", status); } diff --git a/NEW/src/JdeScoping.Client/Auth/AuthStateProvider.cs b/NEW/src/JdeScoping.Client/Auth/AuthStateProvider.cs index ce39beb..e43d902 100644 --- a/NEW/src/JdeScoping.Client/Auth/AuthStateProvider.cs +++ b/NEW/src/JdeScoping.Client/Auth/AuthStateProvider.cs @@ -1,6 +1,6 @@ using System.Net.Http.Json; using System.Security.Claims; -using JdeScoping.Core.ApiContracts.Auth; +using JdeScoping.Core.Models.Auth; using Microsoft.AspNetCore.Components.Authorization; namespace JdeScoping.Client.Auth; diff --git a/NEW/src/JdeScoping.Client/Auth/IUserStorageService.cs b/NEW/src/JdeScoping.Client/Auth/IUserStorageService.cs index 1cc9eb5..2eaa4e0 100644 --- a/NEW/src/JdeScoping.Client/Auth/IUserStorageService.cs +++ b/NEW/src/JdeScoping.Client/Auth/IUserStorageService.cs @@ -1,4 +1,4 @@ -using JdeScoping.Core.ApiContracts.Auth; +using JdeScoping.Core.Models.Auth; namespace JdeScoping.Client.Auth; diff --git a/NEW/src/JdeScoping.Client/Auth/UserStorageService.cs b/NEW/src/JdeScoping.Client/Auth/UserStorageService.cs index 11cf690..e365ba3 100644 --- a/NEW/src/JdeScoping.Client/Auth/UserStorageService.cs +++ b/NEW/src/JdeScoping.Client/Auth/UserStorageService.cs @@ -1,5 +1,5 @@ using System.Text.Json; -using JdeScoping.Core.ApiContracts.Auth; +using JdeScoping.Core.Models.Auth; using Microsoft.JSInterop; namespace JdeScoping.Client.Auth; diff --git a/NEW/src/JdeScoping.Client/Components/Admin/PipelineScheduleSection.razor b/NEW/src/JdeScoping.Client/Components/Admin/PipelineScheduleSection.razor index 1786111..818ea12 100644 --- a/NEW/src/JdeScoping.Client/Components/Admin/PipelineScheduleSection.razor +++ b/NEW/src/JdeScoping.Client/Components/Admin/PipelineScheduleSection.razor @@ -1,5 +1,5 @@ @namespace JdeScoping.Client.Components.Admin -@using JdeScoping.Core.ApiContracts.Pipelines +@using JdeScoping.Core.Models.Pipelines @using JdeScoping.Core.Models.Enums diff --git a/NEW/src/JdeScoping.Client/Pages/Admin/PipelineViewer.razor b/NEW/src/JdeScoping.Client/Pages/Admin/PipelineViewer.razor index 7549519..c0101c0 100644 --- a/NEW/src/JdeScoping.Client/Pages/Admin/PipelineViewer.razor +++ b/NEW/src/JdeScoping.Client/Pages/Admin/PipelineViewer.razor @@ -1,7 +1,7 @@ @page "/admin/pipeline-viewer" @attribute [Authorize] @using JdeScoping.Core.ApiContracts -@using JdeScoping.Core.ApiContracts.Pipelines +@using JdeScoping.Core.Models.Pipelines @using JdeScoping.Core.Models.Enums @inject IPipelineApiClient PipelineApi diff --git a/NEW/src/JdeScoping.Client/Pages/RefreshStatus.razor b/NEW/src/JdeScoping.Client/Pages/RefreshStatus.razor index 0370678..9ab81f8 100644 --- a/NEW/src/JdeScoping.Client/Pages/RefreshStatus.razor +++ b/NEW/src/JdeScoping.Client/Pages/RefreshStatus.razor @@ -31,31 +31,31 @@ } else { - - + - + - - - - - - - - - - - - + + + + + + + + + + + +