refactor: remove unused classes and consolidate ViewModels in Core

Remove 9 unused types from Core (duplicate extension classes, TableSpec, ColumnSpec, LotLocation), move ComponentLotViewModel and OperatorViewModel from Client to Core, and refactor DataSync.Dev to use pipeline-based configuration. Fix Login.razor to use UserInfoDto directly.
This commit is contained in:
Joseph Doherty
2026-01-19 00:13:12 -05:00
parent 80057590f4
commit 7e36bb4225
89 changed files with 1049 additions and 2282 deletions
@@ -2,6 +2,7 @@ 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;
@@ -98,7 +99,8 @@ public class AuthController : ApiControllerBase
new AuthenticationProperties { IsPersistent = false });
_logger.LogInformation("User {Username} logged in successfully", loginModel.Username);
return Ok(new LoginResultModel(true, null, result.User));
var userDto = UserInfoDto.FromUserInfo(result.User!);
return Ok(new LoginResultModel(true, null, userDto));
}
/// <summary>
@@ -122,10 +124,11 @@ public class AuthController : ApiControllerBase
/// <returns>User info on success, 401 if not authenticated</returns>
[HttpGet("me")]
[Authorize]
[ProducesResponseType(typeof(UserInfo), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(UserInfoDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public ActionResult<UserInfo> GetCurrentUser()
public ActionResult<UserInfoDto> GetCurrentUser()
{
return Ok(CurrentUser);
// CurrentUser is guaranteed non-null due to [Authorize] attribute
return Ok(UserInfoDto.FromUserInfo(CurrentUser!));
}
}
@@ -31,7 +31,7 @@ public partial class FileIOController
try
{
using var stream = file.OpenReadStream();
await using var stream = file.OpenReadStream();
var lotViewModels = _parserService.ParseComponentLots(stream);
var lots = await _repository.LookupLotsAsync(lotViewModels, ct);
@@ -31,7 +31,7 @@ public partial class FileIOController
try
{
using var stream = file.OpenReadStream();
await using var stream = file.OpenReadStream();
var itemNumbers = _parserService.ParseItems(stream);
var items = await _repository.LookupItemsAsync(itemNumbers, ct);
@@ -31,7 +31,7 @@ public partial class FileIOController
try
{
using var stream = file.OpenReadStream();
await using var stream = file.OpenReadStream();
var workOrderNumbers = _parserService.ParseWorkOrders(stream);
var workOrders = await _repository.LookupWorkordersAsync(workOrderNumbers, ct);
@@ -149,10 +149,14 @@ public class PipelineController : ControllerBase
matchCols,
config.Destination.ExcludeFromUpdate?.ToList());
// Mass uses massQuery with no parameters; Daily/Hourly use query with parameters
var parameters = config.Source.Parameters?.Select(p => new PipelineParameterDto(
p.Key, p.Value.Format, p.Value.Source)).ToList() ?? [];
var schedules = new PipelineSchedulesDto(
MapSchedule(config.Schedules?.Mass, defaults.Mass),
MapSchedule(config.Schedules?.Daily, defaults.Daily),
MapSchedule(config.Schedules?.Hourly, defaults.Hourly));
MapSchedule(config.Schedules?.Mass, defaults.Mass, config.Source.MassQuery, [], config.PreScripts, config.PostScripts),
MapSchedule(config.Schedules?.Daily, defaults.Daily, config.Source.Query, parameters, config.PreScripts, config.PostScripts),
MapSchedule(config.Schedules?.Hourly, defaults.Hourly, config.Source.Query, parameters, config.PreScripts, config.PostScripts));
return new PipelineConfigDto(
name,
@@ -167,7 +171,11 @@ public class PipelineController : ControllerBase
private static PipelineScheduleDto MapSchedule(
ScheduleConfig? config,
ScheduleConfig defaults)
ScheduleConfig defaults,
string? query,
List<PipelineParameterDto> parameters,
List<string>? preScripts,
List<string>? postScripts)
{
return new PipelineScheduleDto(
config?.Enabled ?? defaults.Enabled,
@@ -176,7 +184,11 @@ public class PipelineController : ControllerBase
config?.ReIndex ?? defaults.ReIndex,
config?.IntervalMinutes > 0 && config.IntervalMinutes != defaults.IntervalMinutes,
config?.PrePurge != null && config.PrePurge != defaults.PrePurge,
config?.ReIndex != null && config.ReIndex != defaults.ReIndex);
config?.ReIndex != null && config.ReIndex != defaults.ReIndex,
query,
parameters,
preScripts,
postScripts);
}
private static ScheduleConfig? GetScheduleConfig(
+5 -7
View File
@@ -1,6 +1,4 @@
using JdeScoping.Core.Models;
using JdeScoping.Core.Models.Infrastructure;
using JdeScoping.Core.Models.Search;
using JdeScoping.Core.ApiContracts.SignalR;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
@@ -11,7 +9,7 @@ namespace JdeScoping.Api.Hubs;
/// </summary>
public class StatusHub : Hub
{
private static StatusUpdate _cachedStatus = new()
private static StatusUpdateDto _cachedStatus = new()
{
Message = "Unknown",
Timestamp = DateTime.UtcNow
@@ -29,7 +27,7 @@ public class StatusHub : Hub
/// Caches the update and broadcasts to all clients.
/// </summary>
/// <param name="statusUpdate">Status update to broadcast</param>
public async Task SetStatus(StatusUpdate statusUpdate)
public async Task SetStatus(StatusUpdateDto statusUpdate)
{
_cachedStatus = statusUpdate;
await Clients.All.SendAsync("statusUpdate", statusUpdate);
@@ -40,7 +38,7 @@ public class StatusHub : Hub
/// Called by clients to get initial cached status on connection.
/// </summary>
/// <returns>The most recent status update</returns>
public StatusUpdate GetCachedStatus()
public StatusUpdateDto GetCachedStatus()
{
return _cachedStatus;
}
@@ -49,7 +47,7 @@ public class StatusHub : Hub
/// Called by controllers/services to broadcast search updates.
/// </summary>
/// <param name="searchUpdate">Search update to broadcast</param>
public async Task PublishSearchUpdate(SearchUpdate searchUpdate)
public async Task PublishSearchUpdate(SearchUpdateDto searchUpdate)
{
await Clients.All.SendAsync("searchUpdate", searchUpdate);
_logger.LogDebug("Search update published: ID={Id}, Status={Status}", searchUpdate.Id, searchUpdate.Status);
@@ -1,6 +1,6 @@
using JdeScoping.Api.Hubs;
using JdeScoping.Core.ApiContracts.SignalR;
using JdeScoping.Core.Interfaces;
using JdeScoping.Core.Models.Infrastructure;
using JdeScoping.Core.Models.Search;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
@@ -34,7 +34,7 @@ public class SearchNotificationService : ISearchNotificationService
{
try
{
var update = new SearchUpdate(search);
var update = SearchUpdateDto.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 = new StatusUpdate(status);
var update = StatusUpdateDto.Create(status);
await _hubContext.Clients.All.SendAsync("statusUpdate", update, ct);
_logger.LogDebug("Status notification sent: {Status}", status);
}